Skip to content

Releases: NerdySoftPaw/python-openpublictransport

v0.2.0 — typed exceptions on API failures

Choose a tag to compare

@NerdySoftPaw NerdySoftPaw released this 16 Sep 18:55
9bd480d

Breaking change

search_stops() returning [] and fetch_departures() returning None now mean "no data" and nothing else. Every failure raises.

Previously each provider logged a non-200 response and handed back an empty result, so a caller could not tell "the search found nothing" apart from "the provider is down" — see NerdySoftPaw/openpublictransport#88.

Migrating

from openpublictransport import ApiError, AuthenticationError, OpenPublicTransportError

try:
    stops = await provider.search_stops(term)
except AuthenticationError:
    ...          # the key was rejected — prompt for credentials
except ApiError as err:
    ...          # err.status holds the HTTP status
except OpenPublicTransportError:
    ...          # timeout, unreachable host, or an unusable payload

if not stops:
    ...          # genuinely no matches

Exception hierarchy

All under OpenPublicTransportError:

Class Raised for
ApiError any non-2xx; carries .status and a truncated .body
AuthenticationError HTTP 401/403 — now a subclass of ApiError
ApiConnectionError host unreachable
ApiTimeoutError request timed out
ApiResponseError a 2xx whose payload cannot be used

AuthenticationError deriving from ApiError means a caller that only cares about "the API failed" catches it too, while one that wants a credential prompt can still single it out.

One HTTP path

BaseProvider._request() replaces all 16 hand-rolled call sites — the seven protocol bases (EFA, FPTF, HAFAS, HAFAS mgate, OTP REST, OTP GraphQL, TRIAS) and the nine standalone providers.

Retry policy: 4xx raises immediately — retrying a rejected key or a dead endpoint only delays the error the user needs to see — while 5xx, timeouts and connection errors keep the existing retry and backoff before raising. The error body travels on the exception, because a provider often explains a rejection only there.

Eight dead raise sites fixed

In otp_base, trias_base, rmv, trafiklab (×2), nta, national_rail and rejseplanen a broad except Exception in the same method swallowed the provider's own AuthenticationError, so HTTP 401 and 403 never reached a caller.

Kept on purpose

  • National Rail still falls back to its bundled station snapshot when Overpass is unreachable.
  • HVV GTI still treats ERROR_TEXT as an unmatched search term rather than a failure.

Tests

83 → 101, including a new suite pinning the retry policy and the empty-versus-failed distinction across every protocol family.

Full changelog: v0.1.16...v0.2.0

v0.1.17 — EFA: accept RapidJSON sent with an XML content type

Choose a tag to compare

@NerdySoftPaw NerdySoftPaw released this 08 Aug 17:44
48f5b01

Fixed

  • EFA: accept RapidJSON payloads sent with an XML content type. VGN (Nuremberg) answers outputFormat=RapidJSON requests with Content-Type: text/xml;;charset=utf-8. aiohttp's strict content-type check rejected those bodies, so station search failed with "no results found" and departures never loaded. Both EFA request paths (fetch_departures, search_stops) now decode with content_type=None; malformed bodies still fall through to the existing error handling. Applies to all 16 EFA providers.

    Fixes openpublictransport#79

Tests

New tests/test_efa_mimetype.py — the fake response mimics aiohttp and raises unless the strict check is disabled, so it fails without the fix.

v0.1.16

Choose a tag to compare

@NerdySoftPaw NerdySoftPaw released this 01 Aug 18:06
1ba37ed

What's Changed

  • feat(hvv): add the official Geofox GTI provider (0.1.16) by @NerdySoftPaw in #16

Full Changelog: v0.1.15...v0.1.16

v0.1.15

Choose a tag to compare

@NerdySoftPaw NerdySoftPaw released this 01 Aug 16:00
f6f37fb

What's Changed

  • fix(efa): map location.properties.platform to the platform attribute (0.1.15) by @NerdySoftPaw in #15

Full Changelog: v0.1.14...v0.1.15

v0.1.14 — ÖBB fix + 6 new providers (NL, LU, NO, US×2, IE, CH)

Choose a tag to compare

@NerdySoftPaw NerdySoftPaw released this 14 Jul 18:01
fe6c002

Fixes

  • ÖBB (Austria): migrate off the permanently-suspended oebb.macistry.com REST backend to ÖBB's own Scotty HAFAS endpoints (fahrplan.oebb.at). Fixes NerdySoftPaw/openpublictransport#50.

New providers

  • NS (Netherlands) — HAFAS Scotty
  • mobilitéit.lu (Luxembourg) — HAFAS Scotty
  • Entur (Norway) — OTP transmodel GraphQL (keyless)
  • BART (San Francisco, USA) — HAFAS mgate
  • DART (Des Moines, USA) — HAFAS mgate
  • Iarnród Éireann / Irish Rail (Ireland) — HAFAS mgate
  • TPG (Geneva, Switzerland) — HAFAS mgate

Internals

  • New HafasBaseProvider (legacy HAFAS "Scotty": ajax-getstop.exe + stboard.exe), tolerant of malformed board XML and 2-/4-digit years.
  • New HafasMgateBaseProvider (modern mgate.exe JSON gateway; unsigned, with an optional checksum/mic-mac signing hook). Transport type derived from prodCtx.catOut.
  • Endpoints/config sourced from public-transport/transport-apis and validated live.

v0.1.12 — National Rail: fix HTTP 500 (SOAPAction/version) + non-blocking snapshot

Choose a tag to compare

@NerdySoftPaw NerdySoftPaw released this 06 Jul 10:36
63d0c97

Fixes

  • National Rail (UK): departures returned HTTP 500 for every station. The SOAPAction was pinned to the request-body ldb version instead of the fixed operation version. Aligned the LDBWS version triple with reference clients: endpoint ldb12.asmx, body namespace 2021-11-01, SOAPAction .../2012-01-13/ldb/GetDepartureBoard. Refs NerdySoftPaw/openpublictransport#39.
  • Station snapshot is now loaded off the event loop (Home Assistant flagged a blocking file read).
  • Non-200 SOAP responses now log the fault reason instead of discarding it.

v0.1.11 — National Rail: snapshot fallback only on Overpass failure

Choose a tag to compare

@NerdySoftPaw NerdySoftPaw released this 02 Jul 17:47
bbc9d70

Fixes

  • National Rail (UK): the offline station snapshot is now used only when the live Overpass (OSM) query actually fails (unreachable / rate-limited), not when Overpass succeeds and legitimately returns no matches — avoiding potentially out-of-date fallback results. Addresses Copilot review feedback on #8.

v0.1.10 — National Rail: offline station snapshot fallback

Choose a tag to compare

@NerdySoftPaw NerdySoftPaw released this 02 Jul 17:40
e676961

Adds

  • National Rail (UK): a bundled offline station snapshot (CRS + name, ~2,855 UK stations) used as a fallback for station search when the live Overpass (OSM) API is unreachable, rate-limited, or returns nothing. Overpass remains the source of truth. The snapshot is a point-in-time extract and is not continuously updated.

v0.1.9 — National Rail: fix empty departure board (OpenLDBWS parsing)

Choose a tag to compare

@NerdySoftPaw NerdySoftPaw released this 02 Jul 17:08
f894b32

Fixes

  • National Rail (UK): departures never parsed — every station returned an empty board ("Invalid or empty API response" in Home Assistant) regardless of the API key. Real OpenLDBWS responses use namespace prefixes containing digits (lt4:, lt5:, lt7: …), which the namespace-stripping step didn't handle, causing an unbound prefix parse error. Refs NerdySoftPaw/openpublictransport#39.

Includes a regression test parsing a realistic multi-namespace response.

v0.1.8 — National Rail: direct CRS code stop search (#39)

Choose a tag to compare

@NerdySoftPaw NerdySoftPaw released this 01 Jul 21:24
83b153b

Fixes

  • National Rail (UK): search_stops() now accepts a 3-letter CRS code (e.g. WIN, RDG) and looks it up directly against the OSM ref:crs tag. Previously only station names matched, so searching by code returned nothing. Fixes NerdySoftPaw/openpublictransport#39.

Includes a regression test for the CRS-code path.