Examples

These examples assume you call the live API where noted. For scripts that hit the network, stay within Jolpica rate limits and prefer Caching and usage statistics for repeated requests.

Terminal query methods (client.get_seasons(), client.query()....get_races(), etc.) return a basef1.domain.parse.ParsedApiResponse: use .pagination, .kind, and typed .data (or basef1.domain.parse.RawTable for unknown tables).

Basic: client and seasons

from basef1 import BaseF1Client
from basef1.domain.tables import SeasonTable

with BaseF1Client() as client:
    envelope = client.get_seasons(limit=100)
    assert isinstance(envelope.data, SeasonTable)
    print(envelope.pagination.total_int, len(envelope.data.seasons))
    print(envelope.data.seasons[0].season)

Intermediate: season calendar and results

from basef1 import BaseF1Client
from basef1.domain.tables import RaceTable

with BaseF1Client() as client:
    races_env = client.query().season(2024).get_races(limit=100)
    assert isinstance(races_env.data, RaceTable)
    for race in races_env.data.races:
        print(race.round, race.race_name)

    results_env = client.query().season(2024).round(1).get_results(limit=100)
    # results_env.data is RaceTable with nested Race rows including Results

Filters and pagination

from basef1 import BaseF1Client
from basef1.domain.tables import SeasonTable

with BaseF1Client() as client:
    monza = client.query().circuit("monza").get_races(limit=50)
    hamilton = client.query().season(2024).driver("hamilton").get_results(limit=50)

    offset = 0
    while True:
        page = client.get_seasons(limit=100, offset=offset)
        total = page.pagination.total_int
        batch = len(page.data.seasons) if isinstance(page.data, SeasonTable) else 0
        if batch == 0:
            break
        offset += batch
        if total is not None and offset >= total:
            break

Standings, laps, pit stops

from basef1 import BaseF1Client
from basef1.domain.tables import SeasonTable

with BaseF1Client() as client:
    q = client.query().season(2024)
    drivers = q.get_driver_standings(limit=100)
    teams = q.get_constructor_standings(limit=100)

    r = client.query().season(2024).round(1)
    laps = r.get_laps(limit=100)
    pits = r.get_pitstops(limit=100)

Advanced: narrow RaceTable and inspect a Race

from basef1 import BaseF1Client
from basef1.domain import Race
from basef1.domain.tables import RaceTable

with BaseF1Client() as client:
    env = client.query().season(2024).round(1).get_results(limit=100)
    assert isinstance(env.data, RaceTable)
    races = env.data.races
    if not races:
        raise SystemExit("No race row in response")
    race: Race = races[0]
    circuit_name = race.circuit.location.locality if race.circuit and race.circuit.location else None
    print(race.race_name, circuit_name)
    for row in race.results[:5]:
        code = row.driver.code if row.driver else None
        print(row.position, code, row.points)

Testing without the network (httpx.MockTransport)

import httpx
from basef1 import BaseF1Client
from basef1.domain.tables import SeasonTable

payload = {
    "MRData": {
        "limit": "30",
        "offset": "0",
        "total": "1",
        "SeasonTable": {"Seasons": [{"season": "2024"}]},
    }
}

transport = httpx.MockTransport(lambda r: httpx.Response(200, json=payload))
with httpx.Client(transport=transport) as http_client:
    client = BaseF1Client(client=http_client, cache=False)
    env = client.get_seasons(limit=30, offset=0)
    assert isinstance(env.data, SeasonTable)
    assert env.data.seasons[0].season == "2024"