Source code for passengersim.config.paths
from __future__ import annotations
from typing import Any
from pydantic import BaseModel, field_validator
[docs]
class Path(BaseModel, extra="forbid"):
"""A travel path from an origin to a destination, comprised of one or more legs."""
path_id: int | None = None
"""Optional numeric identifier for the path."""
orig: str
"""Identifier code for the path origin.
This is typically the IATA airport code for the origin airport, but it may be a
different code if the path is being used in a non-air-travel context, or if the
airport is a hypothetical place that does not have an assigned IATA code.
"""
dest: str
"""Identifier code for the path destination.
This is typically the IATA airport code for the destination airport, but it may
be a different code if the path is being used in a non-air-travel context, or if
the airport is a hypothetical place that does not have an assigned IATA code.
"""
path_quality_index: float
"""A numeric index representing the quality of the path.
Lower values typically indicate a more desirable itinerary. This is typically
the number of connections on the path but could also be some other quality
measure.
"""
legs: list[int]
"""Leg IDs of the legs comprising the path, in order from origin to destination.
At least one leg is required.
"""
@field_validator("legs", mode="before")
@classmethod
def _allow_single_leg(cls, v: Any) -> list[int]:
"""Coerce a bare integer into a one-element list.
Pydantic calls this validator before type coercion, so callers may
supply a single flight number instead of a one-element list.
Parameters
----------
v : int or list of int or Any
The raw (pre-coercion) value supplied for ``legs``.
Returns
-------
list of int
``v`` wrapped in a list when it is a plain integer, otherwise
``v`` unchanged.
"""
if isinstance(v, int):
return [v]
return list(v)
@field_validator("legs")
@classmethod
def _at_least_one_leg(cls, v: Any) -> list[int]:
"""Ensure the path contains at least one leg.
Parameters
----------
v : list of int
The post-coercion list of flight numbers.
Returns
-------
list of int
``v`` unchanged if it contains at least one element.
Raises
------
ValueError
If ``v`` is an empty list.
"""
legs: list[int] = list(v)
if len(legs) < 1:
raise ValueError("path must have at least one leg")
return legs
@property
def market_identifier(self) -> str:
"""A tilde-separated string identifying the origin–destination market.
Returns
-------
str
A string of the form ``"<orig>~<dest>"``, e.g. ``"JFK~LAX"``.
"""
return f"{self.orig}~{self.dest}"