Metadata-Version: 2.4
Name: nfl-espn
Version: 0.1.0
Summary: Python SDK for the ESPN NFL API
Author: Jeff Francis
License: GPL-3.0-only
Project-URL: Homepage, https://github.com/jfrancis42/nfl
Project-URL: Repository, https://github.com/jfrancis42/nfl
Project-URL: Issues, https://github.com/jfrancis42/nfl/issues
Keywords: nfl,football,sports,api,sdk,espn
Classifier: Programming Language :: Python :: 3
Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
Classifier: Operating System :: OS Independent
Classifier: Intended Audience :: Developers
Classifier: Topic :: Software Development :: Libraries
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: requests>=2.31.0
Requires-Dist: urllib3>=2.0.0
Provides-Extra: dev
Requires-Dist: pytest>=7.0; extra == "dev"
Requires-Dist: pytest-cov; extra == "dev"
Dynamic: license-file

# nfl — Python SDK for ESPN's NFL API

A small, typed Python client for the public (but undocumented) JSON API
behind ESPN's NFL pages. No API key or account is needed.

* Typed dataclasses for teams, rosters, scoreboards, game summaries
  (boxscore, drives, scoring plays, leaders), standings, athletes and news —
  with `.raw` on every model for anything not modelled.
* Retries on 5xx responses, optional rate limiting, and a small exception
  hierarchy (`NFLError`, `NFLNotFoundError`, `NFLRateLimitError`, ...).
* Depends only on `requests` and `urllib3`. Python 3.10+.

ESPN publishes no developer program or documentation for this API. It has been
stable, but it can change without notice.

## Install

```bash
pip install nfl-espn
# or, from a checkout:
pip install -e .
```

## Quick start

```python
from nfl import NFLClient

client = NFLClient()

# A week's scores
for game in client.scoreboard.get(week=1, season=2026).games:
    print(f"{game.short_name:12} {game.score_display:8} [{game.status.short_detail}]")

# Division standings
standings = client.standings.get(season=2026)
for entry in standings.get_division("AFC West").entries:
    print(f"{entry.team_display_name:25} {entry.overall}")

# A team and its roster
broncos = client.teams.get(client.teams.BRONCOS)
print(broncos.display_name, broncos.record_str, broncos.standing_summary)
for player in client.teams.roster(client.teams.BRONCOS)[:5]:
    print(f"#{player.jersey or '??'}  {player.full_name}  {player.position_abbreviation}")
```

See [`examples/lions.py`](examples/lions.py) for a fuller example.

## Choosing a season

**A season is named by the year it starts.** `season=2026` is the 2026-27
season: September 2026 through the Super Bowl in February 2027. The playoffs
played in January 2027 are `season=2026`, not 2027.

Leave `season` out and you get the current season.

| Call | Selects the season with | Notes |
|------|-------------------------|-------|
| `scoreboard.get(week=5, season=2026)` | `season` + `week` | Regular season by default; `season_type=1` preseason, `3` postseason. `season` **without** `week` raises `ValueError` |
| `scoreboard.get(week=5)` | `week` | Week 5 of the current season |
| `scoreboard.get(dates="2026-10-04")` | a calendar date | Whatever was played that day; `today()` is the same for today |
| `scoreboard.playoffs(season=2025)` | `season` | Every playoff game of that season (13: Wild Card to Super Bowl, no Pro Bowl) |
| `scoreboard.playoffs(season=2025, week=5)` | `season` + round | 1 Wild Card, 2 Divisional, 3 Conference, 5 Super Bowl (4 is the Pro Bowl) |
| `standings.get(season=2025)` | `season` | Final standings for a finished season, or the standings so far for the current one |
| `teams.schedule(team_id, season=2026)` | `season` | That team's regular-season games |

`games`, `athletes`, `news` and `teams.get`/`roster` take no season: a game
is looked up by its id (from a scoreboard or schedule), and the rest are
always current.

```python
client.scoreboard.get(week=1, season=2026)      # opening week, 2026-27
client.scoreboard.playoffs(season=2025)         # the playoffs played Jan-Feb 2026
client.standings.get(season=2025)               # final 2025 standings
client.standings.get()                          # the current season so far
```

## Endpoints

| Attribute | Covers |
|-----------|--------|
| `client.teams` | teams, rosters, team schedules |
| `client.scoreboard` | scores and schedule by week, date or season; playoffs |
| `client.games` | game summary, boxscore, scoring plays, drives, leaders |
| `client.standings` | division and conference standings |
| `client.athletes` | a player by ESPN id |
| `client.news` | league and team news |

Full reference: [`docs/`](docs/index.md).

## Things the API does that you might not expect

| Behaviour | Notes |
|-----------|-------|
| Seasons are named by their **start** year | `season=2026` is the 2026-27 season, playoffs included |
| The scoreboard ignores `season=` | It selects a season with `dates=YYYY`; the SDK sends that for you |
| A year with no week returns a mixed bag | Preseason, regular season and playoffs together, ignoring the season type; the SDK refuses it |
| The Pro Bowl is postseason week 4 | `playoffs()` leaves it out |
| Three different API hosts | `site.api.espn.com` for most things, `site.web.api.espn.com` for standings, `sports.core.api.espn.com` for athletes — handled internally |
| No player search | Find players through a roster or game data, then look them up by id |
| An unknown team id returns HTTP 400, not 404 | Raised as `NFLHTTPError` |
| Standings carry no points for/against | Point differential is available |
| A drive's net yards can be negative | Penalties |

## Tests

```bash
pip install -e '.[dev]'
python3 -m pytest tests -q
```

The tests are integration tests against the live API (no mocks), so they
need network access.

## Disclaimer

Not affiliated with or endorsed by ESPN or the NFL. The data belongs to them;
this library only makes the requests.

## License

GNU General Public License v3.0 only (GPL-3.0-only) — see [LICENSE](LICENSE).
