Metadata-Version: 2.4
Name: nflmeta
Version: 0.2.2
Summary: Official Python SDK for the NFLMeta API
Author: NFLMeta
License: MIT
Project-URL: Homepage, https://nflmeta.org/api-docs/sdk
Project-URL: Documentation, https://nflmeta.org/api-docs
Project-URL: Source, https://github.com/philippebourdon/NFLMeta
Keywords: nfl,nflmeta,sports,api,sdk,python
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Dynamic: license-file

# `nflmeta`

## Current-season helpers

```python
client.teams.cap_space(season=2026, team_abbr="NE")
client.games.inactives(22773)
client.injuries.list(season=2026, week=1)
client.teams.injuries("NE", season=2026, week=1)
client.players.injuries("player-key", season=2026)
client.players.resolve(["patrick-mahomes", "josh-allen"])
client.teams.roster("NE", year=2026, count=True)
```

Use an initialized server-side client. Cap space is a daily estimate; inspect
`response.meta["observed_at"]` and `response.meta["stale"]`. Inactive status
`not_available` does not mean everyone is active. Injury
`response.meta["current_reserves"]` is current, not historical; distinguish
`reported_pending` from `confirmed` and `report_status` from `game_status`.
List totals may be None or absent. Request count=True where supported, or use
returned/has_more. Existing live and historical analytics methods are unchanged.
Bulk player resolution accepts 1–100 keys per request. Use returned
`requested_player_key` and `player_key` to update your own mapping;
`meta["unresolved"]` names keys with no match. Only returned player records
count toward your row allowance.

Official Python SDK for the NFLMeta API.

## Install

```bash
pip install nflmeta
```

## Quickstart

```python
from nflmeta import NFLMetaClient

client = NFLMetaClient(api_key="YOUR_KEY")

team = client.teams.get("PIT", season=2025)
player = client.players.identity("josh-allen-1996")
usage = client.usage.get()
live = client.live_scores.get()

print(team.data["displayName"])
print(player.data["display_name"])
print(usage.data["quota_remaining"])
```

## What The SDK Does

- sends `X-NFLMeta-Key` automatically when you provide `api_key`
- preserves the API envelope shape: `data`, optional `meta`, plus parsed rate-limit headers
- throws typed HTTP errors for common failure cases
- exposes the main public API surfaces as resource clients instead of forcing raw URL construction
- still gives you a low-level `client.get(path, query={...})` escape hatch for any route not wrapped yet

## Configuration

```python
client = NFLMetaClient(
    api_key="YOUR_KEY",
    base_url="https://nflmeta.org",
    timeout=10.0,
)
```

You can also pass default headers or a custom `transport(url, headers, timeout)` callable if you want the SDK to run through your own HTTP layer in tests or internal tooling.

## Resource Coverage

The Python SDK wraps the same main surfaces as the TypeScript package:

- `health`
- `live_scores`
- `usage`
- `metadata`
- `seasons`
- `teams`
- `players`
- `games`
- `plays`
- `playoff_games`
- `standings`
- `playoffs`
- `super_bowls`
- `history`
- `hall_of_fame`
- `contributors`
- `executives`
- `staff`
- `coaches`
- `assets`
- `all_star_games`
- `stats.players`
- `reference`

```python
client.live_scores.get()
client.plays.summary(season=2024, group_by="team")
client.plays.leaders(season=2024, role="passer")
client.plays.list(game_id=21390, skip_markers=True)
```

`plays.list` is metered per play and the API refuses an unnarrowed request with
`400 invalid_request`: pass `game_id`, or `player`, or `season` together with one
of `week`, `team` or `opponent`. `plays.summary` and `plays.leaders` answer
season-wide questions server-side in tens of rows.

## Errors

- `NFLMetaBadRequestError`
- `NFLMetaUnauthorizedError`
- `NFLMetaNotFoundError`
- `NFLMetaRateLimitError`
- `NFLMetaTimeoutError`
- `NFLMetaError`

## Escape Hatch

```python
raw = client.get("/api/v1/reference/team-colors", query={"limit": 10})
print(raw.data)
```

The path is resolved against `base_url` and has to stay there. A URL on another
origin is refused with `NFLMetaInvalidUrlError` **before** any header is built,
and a redirect that would leave the origin is refused rather than followed —
your API key travels in the `X-NFLMeta-Key` header, and `urllib` forwards every
request header across a cross-origin redirect. Same-origin absolute URLs still
work.

### Selective live-score polling

```python
client.live_scores.get(phase="in")  # Includes halftime and overtime
client.live_scores.get(game_id=12345)
client.live_scores.get(game_ids="12345,12346")  # Comma-separated string
```

Filters select the current live-score window, not historical games. Only returned games count toward row usage; empty results cost zero rows. Request limits still apply. Poll IDs without `phase="in"` to receive final scores. These optional arguments require an SDK release containing this change; existing SDK clients can call the filtered REST URL directly.

## 0.2.0: selected events, historical practice and identity-aware depth charts

Keep returned metadata: unknown distance or attribution is not zero; historical records are not certified pre-kickoff snapshots. Depth-chart `identity_status` describes identity, not vacancy. Player lookup resolves retained aliases; preserve your own player/Favorites IDs. A one-time Sleeper crosswalk can be requested through support; no public external-ID lookup is provided.

```python
events = client.games.defense_special_teams(11565, limit=100, offset=0)
chart = client.teams.depth_chart("NE")
league_charts = client.depth_charts.list(season=2026, limit=100)
changes = client.depth_charts.changes(team="NE", days=7)
history = client.rosters.list(season=2020, week=2)
practice = client.injuries.list(season=2020, date="2020-09-16")
scores = client.live_scores.get(phase="in", game_ids="22834,22835")
```


Live scores return `play_sync` unchanged in `APIResponse.data`. When status is
`matched`, match `last_play_number` to `play_number` for the same `game_id` in
`/api/v1/plays`. Otherwise keep alignment unknown/pending. A matching reference
establishes availability of that play, not simultaneous upstream publication.

## Live play revisions

See [live correction contract](../../docs/live-play-revisions.md) for the game-scoped cursor feed, baseline semantics and finalized-data limits. The new game helper/tool preserves next_cursor and material revisions.
