Skip to content
Python SDK

Official Python SDK 0.3.0

The typed synchronous client covers the six Starter routes, parses quotas and ETags, and validates bulk IDs before any call.

Install

pip install foresportia

Version 0.3.0, Python >=3.9. The client is synchronous and typed.

The six Starter routes, typed

MethodRoute
list_leagues()GET /v1/leagues
list_league_matches(code, …)GET /v1/leagues/{code}/matches
get_match(match_id)GET /v1/matches/{match_id}
get_matches_bulk(match_ids)POST /v1/matches/bulk
list_today_matches()GET /v1/matches/today
list_today_picks(limit=20)GET /v1/picks/today
from foresportia import ForesportiaClient

with ForesportiaClient.from_env() as client:
    leagues = client.list_leagues()
    bulk = client.get_matches_bulk([match_id_1, match_id_2])

for league in leagues.data:
    print(league.code, league.matches_available)

for error in bulk.data.errors:
    print("failed:", error.match_id, error.code)

Read verified historical summaries

Use include="past" on list_league_matches(). Historical rows retain the probabilities and pick published before kickoff, then expose the verified final result.

from foresportia import ForesportiaClient

with ForesportiaClient.from_env() as client:
    response = client.list_league_matches(
        "SUE",
        include="past",
        days=7,
        limit=50,
    )

    for match in response.data:
        print(
            match.kickoff,
            match.home_team,
            match.away_team,
            match.result_score,
            match.pick,
        )

Automatic pagination

SDK 0.3.0 also provides iter_league_matches(), which follows next_cursor lazily while keeping the same filters.

from foresportia import ForesportiaClient

with ForesportiaClient.from_env() as client:
    for match in client.iter_league_matches(
        "SUE",
        include="past",
        days=7,
        limit=50,
    ):
        print(match.kickoff, match.result_score, match.pick)

For a full worked example that charts upcoming matches, markets, and verified history with list_league_history(), follow the football dashboard tutorial.

Responses, quotas, and ETags

Each typed method returns an ApiResponse exposing data (typed result), payload (raw dict), etag, quota (parsed headers), and status_code. Passing etag= sends If-None-Match; a 304 is a normal response (response.not_modified), never a generic error.

In SDK 0.3.0, league-match responses also expose next_cursor, history_available_from, and history_entitlement_days as typed properties. Additional counters, including historical_matches_available, remain available in response.payload.

first = client.get_match(match_id)
second = client.get_match(match_id, etag=first.etag)
detail = first.data if second.not_modified else second.data

Errors and bulk validation

Errors are typed: authentication (401), authorization (403), not found (404), validation (400/422), rate limit (429), concurrency limit, server (5xx), and transport. Bulk IDs are validated client-side (1 to 100 unique fsm:v1:* IDs) before any network call, and per-ID failures are reported without hiding successful results.

Retries are disabled by default: a request that times out client-side may already have been counted against your quota, so each retry can consume an extra unit. Enable them explicitly with max_retries=2.

PyPI · SDK documentation · Source and examples