Skip to content

Legs

Leg

Bases: BaseModel

Source code in passengersim/config/legs.py
class Leg(BaseModel, extra="forbid"):
    leg_id: int | None = None
    """A unique identifier for this leg.

    Each leg in a network should have a globally unique identifier (i.e. even
    if the carrier is different, `leg_id` values should be unique.  Note this
    is not the same as the `fltno`, which is a label analogous to flight numbers
    in practice, which don't need to be unique.  If the leg_id is not provided,
    the `fltno` is used, unless the simulation already has a leg with that
    `leg_id`, in which case a new unique leg_id will be generated.
    """

    carrier: str
    """The carrier name for this leg."""

    fltno: int
    """A flight number identifier for this leg.

    Flight numbers do not need to be unique.
    """

    orig: str
    """Origination location for this leg."""

    orig_timezone: str | None = None
    """Timezone name for the origination location for this leg."""

    dest: str
    """Destination location for this leg."""

    dest_timezone: str | None = None
    """Timezone name for the destination location for this leg."""

    #    date: datetime = datetime.fromisoformat("2020-03-01")
    date: datetime = datetime(2020, 3, 1, tzinfo=UTC)
    """Departure date for this leg.
       The initial load is local, so we have a psuedo-timestamp here, we're avoiding local timezones
       In the overall model validation, we'll unpack it to HH:MM and use the timezone
       to get the true UTC value"""

    arr_day: int = 0
    """If the arrival time is on a different day, this is offset in days.

    This will usually be zero (arrival date is same as departure date) but will
    sometimes be 1 (arrives next day) or in a few pathological cases -1 or +2
    (for travel across the international dateline).
    """

    dep_time: int
    """Departure time for this leg in Unix time.

    In input files, this can be specified as a string in the format "HH:MM",
    with the hour in 24-hour format.

    Unix time is the number of seconds since 00:00:00 UTC on 1 Jan 1970."""

    dep_time_offset: int = 0

    @property
    def dep_localtime(self) -> datetime:
        """Departure time for this leg in local time at the origin."""
        t = datetime.fromtimestamp(self.dep_time, tz=UTC)
        if self.orig_timezone is not None:
            z = ZoneInfo(self.orig_timezone)
            t = t.astimezone(z)
        return t

    arr_time: int
    """Arrival time for this leg in Unix time.

    In input files, this can be specified as a string in the format "HH:MM",
    with the hour in 24-hour format.

    Unix time is the number of seconds since 00:00:00 UTC on 1 Jan 1970."""

    arr_time_offset: int = 0

    @property
    def arr_localtime(self) -> datetime:
        """Arrival time for this leg in local time at the destination."""
        t = datetime.fromtimestamp(self.arr_time, tz=UTC)
        if self.dest_timezone is not None:
            z = ZoneInfo(self.dest_timezone)
            t = t.astimezone(z)
        return t

    time_adjusted: bool = False
    capacity: int | dict[str, int]
    distance: float | None = None

    @field_validator("date", mode="before")
    def _date_from_string(cls, v):
        if isinstance(v, str):
            v = datetime.fromisoformat(v)
        if v.tzinfo is None:
            # when no timezone is specified, assume UTC (not naive)
            v = v.replace(tzinfo=UTC)
        return v

    @field_serializer("date", when_used="always")
    def serialize_date(self, date: datetime) -> str:
        if date.tzinfo is None:
            date = date.replace(tzinfo=UTC)
        return date.isoformat()

    @field_validator("dep_time", "arr_time", mode="before")
    def _timestring_to_int(cls, v, info: ValidationInfo):
        if isinstance(v, str) and ":" in v:
            dep_time_str = v.split(":")
            hh, mm = int(dep_time_str[0]), int(dep_time_str[1])
            v = create_timestamp(info.data["date"], 0, hh, mm)
        if info.field_name == "arr_time":
            if v < info.data["dep_time"] and info.data["arr_day"] == 0:
                v += 86400  # add a day (in seconds) as arr time is next day
            elif info.data["arr_day"] != 0:
                v += 86400 * info.data["arr_day"]  # adjust day[s] (in seconds)
        return v

    tags: dict[str, str] = {}
    """Optional dictionary of tags associated with this leg.

    Tags can be used to store arbitrary key-value pairs of information related to
    this leg. This may be useful for categorization, filtering, or adding metadata.
    Tags can also be used in RM actions to apply different strategies based on
    leg characteristics. For example, a tag could indicate whether a leg is
    a "short-haul" or "long-haul" flight, allowing RM actions to adjust their
    behavior accordingly.
    """

arr_day class-attribute instance-attribute

arr_day: int = 0

If the arrival time is on a different day, this is offset in days.

This will usually be zero (arrival date is same as departure date) but will sometimes be 1 (arrives next day) or in a few pathological cases -1 or +2 (for travel across the international dateline).

arr_localtime property

arr_localtime: datetime

Arrival time for this leg in local time at the destination.

arr_time instance-attribute

arr_time: int

Arrival time for this leg in Unix time.

In input files, this can be specified as a string in the format "HH:MM", with the hour in 24-hour format.

Unix time is the number of seconds since 00:00:00 UTC on 1 Jan 1970.

arr_time_offset class-attribute instance-attribute

arr_time_offset: int = 0

capacity instance-attribute

capacity: int | dict[str, int]

carrier instance-attribute

carrier: str

The carrier name for this leg.

date class-attribute instance-attribute

date: datetime = datetime(2020, 3, 1, tzinfo=UTC)

Departure date for this leg. The initial load is local, so we have a psuedo-timestamp here, we're avoiding local timezones In the overall model validation, we'll unpack it to HH:MM and use the timezone to get the true UTC value

dep_localtime property

dep_localtime: datetime

Departure time for this leg in local time at the origin.

dep_time instance-attribute

dep_time: int

Departure time for this leg in Unix time.

In input files, this can be specified as a string in the format "HH:MM", with the hour in 24-hour format.

Unix time is the number of seconds since 00:00:00 UTC on 1 Jan 1970.

dep_time_offset class-attribute instance-attribute

dep_time_offset: int = 0

dest instance-attribute

dest: str

Destination location for this leg.

dest_timezone class-attribute instance-attribute

dest_timezone: str | None = None

Timezone name for the destination location for this leg.

distance class-attribute instance-attribute

distance: float | None = None

fltno instance-attribute

fltno: int

A flight number identifier for this leg.

Flight numbers do not need to be unique.

leg_id class-attribute instance-attribute

leg_id: int | None = None

A unique identifier for this leg.

Each leg in a network should have a globally unique identifier (i.e. even if the carrier is different, leg_id values should be unique. Note this is not the same as the fltno, which is a label analogous to flight numbers in practice, which don't need to be unique. If the leg_id is not provided, the fltno is used, unless the simulation already has a leg with that leg_id, in which case a new unique leg_id will be generated.

orig instance-attribute

orig: str

Origination location for this leg.

orig_timezone class-attribute instance-attribute

orig_timezone: str | None = None

Timezone name for the origination location for this leg.

tags class-attribute instance-attribute

tags: dict[str, str] = {}

Optional dictionary of tags associated with this leg.

Tags can be used to store arbitrary key-value pairs of information related to this leg. This may be useful for categorization, filtering, or adding metadata. Tags can also be used in RM actions to apply different strategies based on leg characteristics. For example, a tag could indicate whether a leg is a "short-haul" or "long-haul" flight, allowing RM actions to adjust their behavior accordingly.

time_adjusted class-attribute instance-attribute

time_adjusted: bool = False

serialize_date

serialize_date(date: datetime) -> str
Source code in passengersim/config/legs.py
@field_serializer("date", when_used="always")
def serialize_date(self, date: datetime) -> str:
    if date.tzinfo is None:
        date = date.replace(tzinfo=UTC)
    return date.isoformat()