API reference¶
Public symbols are re-exported from the basef1 package. Submodule pages below list implementation modules.
For client-side observability types, see basef1.client.UsageSnapshot and basef1.client.RequestLogEntry under basef1.client.
basef1.client¶
HTTP client for the Jolpica F1 API.
- class basef1.client.BaseF1Client(*, base_url: str = DEFAULT_BASE_URL, timeout: float | Timeout | None = 30.0, client: Client | None = None, cache: TTLCache | SQLiteCache | Literal[False] | None = None, cache_backend: Literal['memory', 'sqlite'] = 'memory', cache_path: str | Path | None = None, cache_ttl: float | None = None, cache_max_entries: int = 256, request_log_maxlen: int | None = 512)¶
Bases:
objectSync client for https://api.jolpi.ca/ergast/f1 (JSON).
By default responses are cached in memory (
TTLCache) to reduce duplicate GET traffic. Passcache_backend="sqlite"for a persistent local SQLite cache,cache=Falseto disable caching, or passcache=/cache_ttl=to customize.Pass a custom
httpx.Clientfor tests or advanced configuration. Ifclientis omitted, an internal client is created and closed when this instance is used as a context manager.request_log_maxlenbounds the in-memory request log (None= unlimited).- stats(*, file: TextIO | None = None) None¶
Print a human-readable usage summary (logical vs HTTP vs cache).
- usage_snapshot() UsageSnapshot¶
Return current usage counters and the full in-memory request log.
- class basef1.client.RequestLogEntry(method: str, url: str, params: tuple[tuple[str, Any], ...], source: Literal['cache', 'network'])¶
Bases:
NamedTupleOne logical client request (cache or network).
- class basef1.client.UsageSnapshot(logical_requests: int, http_requests: int, cache_hits: int, caching_enabled: bool, request_log: tuple[RequestLogEntry, ...])¶
Bases:
NamedTuplePoint-in-time usage counters and request log (newest last).
- request_log: tuple[RequestLogEntry, ...]¶
Alias for field number 4
basef1.query¶
Chainable path builder for Jolpica / Ergast-style URLs.
- class basef1.query.F1Query(client: BaseF1Client, segments: list[str])¶
Bases:
objectBuild filter path segments, then call a terminal resource method.
Invalid segment ordering is possible if methods are chained incorrectly; that matches raw REST usage.
round()requiresseason()to have been called immediately before (last segment is a season year orcurrent).
basef1.models¶
Lightweight response wrappers.
- class basef1.models.ApiResponse(raw: dict[str, Any])¶
Bases:
objectParsed JSON body with helpers for MRData and pagination.
- get_data() dict[str, Any]¶
Return the primary data table under
MRData(e.g.RaceTable), without hard-coding the key.Tries keys in
MRDATA_TABLE_PRIORITYfirst, then any other*Tabledict value (excluding metadata keys). Returns{}if none found.
- parse() ParsedApiResponse¶
Parse MRData into
ParsedApiResponse.
basef1.cache¶
HTTP response caches for idempotent GET responses.
- class basef1.cache.ResponseCache(*args, **kwargs)¶
Bases:
ProtocolMinimal cache interface used by
basef1.client.BaseF1Client.
- class basef1.cache.SQLiteCache(path: str | Path, ttl_seconds: float, *, clock: Callable[[], float] | None = None)¶
Bases:
objectThread-safe on-disk TTL cache backed by SQLite.
Entries expire after
ttl_seconds. The database file is created if missing.
- class basef1.cache.TTLCache(max_entries: int, ttl_seconds: float, *, clock: Callable[[], float] | None = None)¶
Bases:
objectThread-safe in-memory LRU-ish cache: entries expire after
ttl_seconds; when full, the oldest inserted entry is evicted.
- basef1.cache.cache_key_for_request(method: str, url: str, params: dict[str, Any] | None) str¶
Stable cache key for HTTP
method,url, and queryparams.
basef1.exceptions¶
Client errors.
basef1.constants¶
MRData keys shared across Jolpica / Ergast-style JSON responses.
basef1.domain¶
Typed domain models for Jolpica / Ergast JSON datas.
- class basef1.domain.AverageSpeed(units: 'str | None' = None, speed: 'str | None' = None)¶
Bases:
JolpicaModel- classmethod from_dict(data: dict[str, Any]) AverageSpeed¶
- class basef1.domain.Circuit(circuit_id: 'str | None' = None, url: 'str | None' = None, circuit_name: 'str | None' = None, location: 'Location | None' = None)¶
Bases:
JolpicaModel
- class basef1.domain.CircuitTable(circuits: 'list[Circuit]' = <factory>)¶
Bases:
JolpicaModel- classmethod from_dict(data: dict[str, Any]) CircuitTable¶
- class basef1.domain.Constructor(constructor_id: 'str | None' = None, url: 'str | None' = None, name: 'str | None' = None, nationality: 'str | None' = None)¶
Bases:
JolpicaModel- classmethod from_dict(data: dict[str, Any]) Constructor¶
- class basef1.domain.ConstructorStandingRow(position: 'str | None' = None, position_text: 'str | None' = None, points: 'str | None' = None, wins: 'str | None' = None, constructor: 'Constructor | None' = None)¶
Bases:
JolpicaModel- constructor: Constructor | None = None¶
- classmethod from_dict(data: dict[str, Any]) ConstructorStandingRow¶
- class basef1.domain.ConstructorTable(constructors: 'list[Constructor]' = <factory>)¶
Bases:
JolpicaModel- constructors: list[Constructor]¶
- classmethod from_dict(data: dict[str, Any]) ConstructorTable¶
- class basef1.domain.Driver(driver_id: 'str | None' = None, permanent_number: 'str | None' = None, code: 'str | None' = None, url: 'str | None' = None, given_name: 'str | None' = None, family_name: 'str | None' = None, date_of_birth: 'str | None' = None, nationality: 'str | None' = None)¶
Bases:
JolpicaModel
- class basef1.domain.DriverStandingRow(position: 'str | None' = None, position_text: 'str | None' = None, points: 'str | None' = None, wins: 'str | None' = None, driver: 'Driver | None' = None, constructors: 'list[Constructor]' = <factory>)¶
Bases:
JolpicaModel- constructors: list[Constructor]¶
- classmethod from_dict(data: dict[str, Any]) DriverStandingRow¶
- class basef1.domain.DriverTable(drivers: 'list[Driver]' = <factory>)¶
Bases:
JolpicaModel- classmethod from_dict(data: dict[str, Any]) DriverTable¶
- class basef1.domain.FastestLap(rank: 'str | None' = None, lap: 'str | None' = None, time: 'TimeElement | None' = None, average_speed: 'AverageSpeed | None' = None)¶
Bases:
JolpicaModel- average_speed: AverageSpeed | None = None¶
- classmethod from_dict(data: dict[str, Any]) FastestLap¶
- time: TimeElement | None = None¶
- class basef1.domain.JolpicaModel¶
Bases:
objectMixin-style base: subclasses must be
@dataclassinstances.
- class basef1.domain.LapRow(number: 'str | None' = None, timings: 'list[LapTimingEntry]' = <factory>)¶
Bases:
JolpicaModel- timings: list[LapTimingEntry]¶
- class basef1.domain.LapTimingEntry(driver_id: 'str | None' = None, position: 'str | None' = None, time: 'str | None' = None)¶
Bases:
JolpicaModel- classmethod from_dict(data: dict[str, Any]) LapTimingEntry¶
- class basef1.domain.Location(lat: 'str | None' = None, longitude: 'str | None' = None, locality: 'str | None' = None, country: 'str | None' = None)¶
Bases:
JolpicaModel
- class basef1.domain.ParsedApiResponse(kind: str | None, pagination: Pagination, data: RaceTable | SeasonTable | DriverTable | ConstructorTable | CircuitTable | StatusTable | StandingsTable | RawTable)¶
Bases:
objectTyped view of an
ApiResponse.- data: RaceTable | SeasonTable | DriverTable | ConstructorTable | CircuitTable | StatusTable | StandingsTable | RawTable¶
- pagination: Pagination¶
- class basef1.domain.PitStopRow(driver_id: 'str | None' = None, lap: 'str | None' = None, stop: 'str | None' = None, time: 'str | None' = None, duration: 'str | None' = None)¶
Bases:
JolpicaModel- classmethod from_dict(data: dict[str, Any]) PitStopRow¶
- class basef1.domain.QualifyingResult(number: 'str | None' = None, position: 'str | None' = None, driver: 'Driver | None' = None, constructor: 'Constructor | None' = None, q1: 'str | None' = None, q2: 'str | None' = None, q3: 'str | None' = None)¶
Bases:
JolpicaModel- constructor: Constructor | None = None¶
- classmethod from_dict(data: dict[str, Any]) QualifyingResult¶
- class basef1.domain.Race(season: 'str | None' = None, round: 'str | None' = None, url: 'str | None' = None, race_name: 'str | None' = None, circuit: 'Circuit | None' = None, date: 'str | None' = None, time: 'str | None' = None, first_practice: 'Session | None' = None, second_practice: 'Session | None' = None, third_practice: 'Session | None' = None, qualifying: 'Session | None' = None, sprint: 'Session | None' = None, sprint_qualifying: 'Session | None' = None, sprint_shootout: 'Session | None' = None, results: 'list[RaceResult]' = <factory>, sprint_results: 'list[RaceResult]' = <factory>, qualifying_results: 'list[RaceResult]' = <factory>, laps: 'list[LapRow]' = <factory>, pit_stops: 'list[PitStopRow]' = <factory>)¶
Bases:
JolpicaModel- pit_stops: list[PitStopRow]¶
- qualifying_results: list[RaceResult]¶
- results: list[RaceResult]¶
- sprint_results: list[RaceResult]¶
- class basef1.domain.RaceResult(number: 'str | None' = None, position: 'str | None' = None, position_text: 'str | None' = None, points: 'str | None' = None, grid: 'str | None' = None, laps: 'str | None' = None, status: 'str | None' = None, driver: 'Driver | None' = None, constructor: 'Constructor | None' = None, time: 'TimeElement | None' = None, fastest_lap: 'FastestLap | None' = None)¶
Bases:
JolpicaModel- constructor: Constructor | None = None¶
- fastest_lap: FastestLap | None = None¶
- classmethod from_dict(data: dict[str, Any]) RaceResult¶
- time: TimeElement | None = None¶
- class basef1.domain.RaceTable(season: 'str | None' = None, round: 'str | None' = None, circuit_id: 'str | None' = None, driver_id: 'str | None' = None, constructor_id: 'str | None' = None, races: 'list[Race]' = <factory>)¶
Bases:
JolpicaModel
- class basef1.domain.RawTable(kind: str | None, data: dict[str, Any])¶
Bases:
objectFallback when MRData contains an unknown
*Tablekey or no table.
- class basef1.domain.Season(season: 'str | None' = None, url: 'str | None' = None)¶
Bases:
JolpicaModel
- class basef1.domain.SeasonTable(seasons: 'list[Season]' = <factory>)¶
Bases:
JolpicaModel- classmethod from_dict(data: dict[str, Any]) SeasonTable¶
- class basef1.domain.Session(date: str | None = None, time: str | None = None)¶
Bases:
JolpicaModelPractice / qualifying / sprint session slot with date and time.
- class basef1.domain.StandingsList(season: 'str | None' = None, round: 'str | None' = None, driver_standings: 'list[DriverStandingRow]' = <factory>, constructor_standings: 'list[ConstructorStandingRow]' = <factory>)¶
Bases:
JolpicaModel- constructor_standings: list[ConstructorStandingRow]¶
- driver_standings: list[DriverStandingRow]¶
- classmethod from_dict(data: dict[str, Any]) StandingsList¶
- class basef1.domain.StandingsTable(season: 'str | None' = None, round: 'str | None' = None, driver_id: 'str | None' = None, constructor_id: 'str | None' = None, standings_lists: 'list[StandingsList]' = <factory>)¶
Bases:
JolpicaModel- classmethod from_dict(data: dict[str, Any]) StandingsTable¶
- standings_lists: list[StandingsList]¶
- class basef1.domain.StatusRow(status_id: 'str | None' = None, status: 'str | None' = None)¶
Bases:
JolpicaModel
- class basef1.domain.StatusTable(statuses: 'list[StatusRow]' = <factory>)¶
Bases:
JolpicaModel- classmethod from_dict(data: dict[str, Any]) StatusTable¶
- class basef1.domain.TimeElement(millis: 'str | None' = None, time: 'str | None' = None)¶
Bases:
JolpicaModel- classmethod from_dict(data: dict[str, Any]) TimeElement¶
- basef1.domain.ensure_list(value: Any) list[Any]¶
Normalize Ergast single-object-or-list JSON to a list.
- basef1.domain.parse_api_response(resp: ApiResponse) ParsedApiResponse¶
Parse
respinto aParsedApiResponsebased on the MRData table key.