Add full type annotations and black formatting across all modules
Annotated all functions with mypy --strict-compatible types (-> None, dict[str, Any], Generator types, etc.), added # type: ignore for untyped third-party libs (lxml), and reformatted with black. All 18 source files now pass mypy --strict with zero errors. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
453d6244ec
commit
13c4341f3a
14 changed files with 1802 additions and 974 deletions
|
|
@ -6,6 +6,8 @@ Returns per-train cheapest standard-class fare with restrictions already applied
|
|||
Cache for 30 days — fares rarely change.
|
||||
"""
|
||||
|
||||
from typing import Any, Generator
|
||||
|
||||
import httpx
|
||||
|
||||
_API_URL = "https://api.gwr.com/api/shopping/journeysearch"
|
||||
|
|
@ -16,7 +18,7 @@ _WALKON_CODES = {"SSS", "SVS", "SDS", "CDS"}
|
|||
_MAX_PAGES = 20
|
||||
|
||||
|
||||
def _headers() -> dict:
|
||||
def _headers() -> dict[str, str]:
|
||||
return {
|
||||
"user-agent": (
|
||||
"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 "
|
||||
|
|
@ -37,7 +39,7 @@ def _request_body(
|
|||
travel_date: str,
|
||||
conversation_token: str | None,
|
||||
later: bool,
|
||||
) -> dict:
|
||||
) -> dict[str, Any]:
|
||||
return {
|
||||
"IsNextOutward": False,
|
||||
"IsPreviousOutward": False,
|
||||
|
|
@ -83,7 +85,7 @@ def _run_pages(
|
|||
travel_date: str,
|
||||
first_class: bool = False,
|
||||
direction: str = "to_paddington",
|
||||
):
|
||||
) -> Generator[tuple[str, list[Any]], None, None]:
|
||||
"""
|
||||
Iterate all pages of GWR journey search results.
|
||||
|
||||
|
|
@ -96,7 +98,9 @@ def _run_pages(
|
|||
later = False
|
||||
from_code, to_code = _od_codes(station_crs, direction)
|
||||
for _ in range(_MAX_PAGES):
|
||||
body = _request_body(from_code, to_code, travel_date, conversation_token, later)
|
||||
body = _request_body(
|
||||
from_code, to_code, travel_date, conversation_token, later
|
||||
)
|
||||
if first_class:
|
||||
body["firstclass"] = True
|
||||
body["standardclass"] = False
|
||||
|
|
@ -121,7 +125,7 @@ def _run_pages_batched(
|
|||
travel_date: str,
|
||||
first_class: bool = False,
|
||||
direction: str = "to_paddington",
|
||||
):
|
||||
) -> Generator[list[tuple[str, list[Any]]], None, None]:
|
||||
"""
|
||||
Like _run_pages but yields one list of (dep_time, fares_list) per API page call,
|
||||
allowing callers to stream results a page at a time.
|
||||
|
|
@ -132,7 +136,9 @@ def _run_pages_batched(
|
|||
later = False
|
||||
from_code, to_code = _od_codes(station_crs, direction)
|
||||
for _ in range(_MAX_PAGES):
|
||||
body = _request_body(from_code, to_code, travel_date, conversation_token, later)
|
||||
body = _request_body(
|
||||
from_code, to_code, travel_date, conversation_token, later
|
||||
)
|
||||
if first_class:
|
||||
body["firstclass"] = True
|
||||
body["standardclass"] = False
|
||||
|
|
@ -157,7 +163,7 @@ def _run_pages_batched(
|
|||
|
||||
def fetch(
|
||||
station_crs: str, travel_date: str, direction: str = "to_paddington"
|
||||
) -> dict[str, dict]:
|
||||
) -> dict[str, dict[str, Any]]:
|
||||
"""
|
||||
Fetch GWR walk-on single fares for the selected Paddington direction.
|
||||
|
||||
|
|
@ -165,7 +171,7 @@ def fetch(
|
|||
where price is in £ and only the cheapest available standard-class walk-on
|
||||
ticket per departure (with restrictions already applied by GWR) is kept.
|
||||
"""
|
||||
result: dict[str, dict] = {}
|
||||
result: dict[str, dict[str, Any]] = {}
|
||||
for dep_time, fares in _run_pages(station_crs, travel_date, direction=direction):
|
||||
cheapest = None
|
||||
for fare in fares:
|
||||
|
|
@ -193,7 +199,7 @@ def fetch(
|
|||
|
||||
def fetch_advance(
|
||||
station_crs: str, travel_date: str, direction: str = "to_paddington"
|
||||
) -> dict[str, dict]:
|
||||
) -> dict[str, dict[str, Any]]:
|
||||
"""
|
||||
Fetch advance fares: cheapest standard advance and first-class advance per departure.
|
||||
|
||||
|
|
@ -201,7 +207,7 @@ def fetch_advance(
|
|||
Returns {departure_time: {'advance_std': dict or None, 'advance_1st': dict or None}}
|
||||
where each sub-dict has keys 'ticket', 'price', 'code'.
|
||||
"""
|
||||
std_advance: dict[str, dict] = {}
|
||||
std_advance: dict[str, dict[str, Any]] = {}
|
||||
for dep_time, fares in _run_pages(
|
||||
station_crs, travel_date, first_class=False, direction=direction
|
||||
):
|
||||
|
|
@ -227,7 +233,7 @@ def fetch_advance(
|
|||
"code": cheapest["code"],
|
||||
}
|
||||
|
||||
first_advance: dict[str, dict] = {}
|
||||
first_advance: dict[str, dict[str, Any]] = {}
|
||||
for dep_time, fares in _run_pages(
|
||||
station_crs, travel_date, first_class=True, direction=direction
|
||||
):
|
||||
|
|
@ -260,7 +266,7 @@ def fetch_advance(
|
|||
|
||||
def fetch_advance_streaming(
|
||||
station_crs: str, travel_date: str, direction: str = "to_paddington"
|
||||
):
|
||||
) -> Generator[dict[str, dict[str, Any]], None, None]:
|
||||
"""
|
||||
Generator yielding partial advance fare dicts one GWR API page at a time.
|
||||
|
||||
|
|
@ -272,7 +278,7 @@ def fetch_advance_streaming(
|
|||
for batch in _run_pages_batched(
|
||||
station_crs, travel_date, first_class=False, direction=direction
|
||||
):
|
||||
page: dict[str, dict] = {}
|
||||
page: dict[str, dict[str, Any]] = {}
|
||||
for dep_time, fares in batch:
|
||||
cheapest = None
|
||||
for fare in fares:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue