# espn_api: a Python client for ESPN's fantasy league data

> espn_api is an MIT-licensed Python package that pulls fantasy football and basketball data out of ESPN's own Fantasy API for public or private leagues. It is a thin, readable client rather than a data platform, and the mismatch between its Python floor and its formatter settings is a small sign of how young the 1.0 line is.

**cwendt94/espn-api** — ESPN Fantasy API! (Football, Basketball)

- Repository: https://github.com/cwendt94/espn-api
- Stars: 994 · Forks: 295
- Language: Python
- License: MIT
- Published: 2026-10-20 · Updated: 2026-10-20 · Language: en
- Canonical page: https://hysenlabs.com/projects/cwendt94-espn-api

## What the package wraps and who reaches for it

espn_api is a client for an interface that already exists: ESPN's Fantasy API. The package uses that API to extract data from any public or private league, and the point is to give you a Python object model of a league rather than raw JSON that you have to parse yourself. The audience is developers building their own tools, dashboards, trackers or analyses on top of league data, and the package is deliberately small in scope: it does not host data, it does not schedule jobs, and it does not provide a UI. The README credits rbarton65/espnff as the project it was inspired by and based on, which is worth knowing if you are looking for prior art on the same endpoints. The project has had a stable 1.x line since October 2026, with v1.0.0 published on 2026-10-02, v1.0.1 on 2026-10-09 and v0.46.0 back in March, and the last push was on 2026-10-19.

## One League class, one module per sport

The public surface is small. You import a League class from the module for your sport, and you construct it with a league identifier and a year:

```python
from espn_api.football import League
league = League(league_id=222, year=2019)
```

The same class name is exported for each sport, so the shape of the code stays the same when you move from football to basketball:

```python
from espn_api.basketball import League
from espn_api.hockey import League
from espn_api.baseball import League
```

The README points to the project wiki for the getting started material and the API detail, which is where the list of properties and methods belongs. That split is sensible for a package of this size, but it also means the README alone does not tell you which attributes a League object exposes, how a live scoring week is selected, or how historical data is reached. If you are evaluating the library, the wiki is the first thing to open, not the readme. One inconsistency is easy to trip over: the description names football and basketball as supported and says NHL, MLB and WNBA are in development, yet the usage example already imports hockey and baseball League classes.

## Debug mode prints the ESPN request and response traffic

Because the package is a thin client over a moving interface, being able to see the raw traffic is a first class feature rather than a logging afterthought. Passing debug=True to the constructor makes the application print all requests and the responses from ESPN's API to the console:

```python
league = League(league_id=1245, year=2019, debug=True)
```

The README's own advice is to pipe that console output to a text file, since there is a lot of data. That output becomes the diagnostic you attach to a bug report. The issue reporting instructions are specific: open a new issue with a brief description of the bug in the title, and add which sport it is, since football and basketball are separate code paths. Then run in debug mode, find the last log line before the crash, and paste it into the issue description with the line number of the crash. The maintainer states an intention to comment on issues promptly with thoughts and a possible fix, and the project also has a discussions area for questions about the package or the ESPN API data that do not belong in a bug report.

## pip for users, uv for contributors

Installing the released package is a single command:

```bash
pip install espn_api
```

Working on the package itself needs a clone and the uv environment manager, which the project uses to keep the dependency and environment setup reproducible:

```bash
git clone https://github.com/cwendt94/espn-api
cd espn-api
uv sync
```

For contributors there is an extra dependency group:

```bash
uv sync --extra dev
```

The three development tasks are all run through uv, which keeps them off the developer's global environment. The unit tests exclude the integration directory, so the fast run is `uv run pytest tests --ignore-glob='**/integration/**'`. Omitting that option runs the whole suite, including the tests that hit the live ESPN API, which is a deliberate choice: a contributor can separate the fast, deterministic run from the one that proves the upstream contract still holds. Formatting and type checking are configured in the project file rather than left to taste:

```bash
uv run black espn_api tests
```

```bash
uv run mypy espn_api
```

The dev group also brings in pytest-cov for coverage, requests-mock for stubbing HTTP in tests, and types-requests for the type checker, and the repository carries a codecov configuration and a continuous integration workflow, so coverage is tracked rather than assumed.

## A Python floor that disagrees with the tooling settings

The packaging metadata is where the project shows its age. The project requires Python 3.10 or newer, and the classifier and the runtime dependency set match that: requests with a narrow version range, urllib3, and idna. The version number itself is dynamic, read from espn_api._version.__version__ at build time, with a small setup.py that calls setup() and nothing else, which is the modern minimal shim for a setuptools build. The interesting mismatch is in the tool configuration. Black is set to a line length of 88 with a target version of py38, and mypy is configured with python_version 3.8 and ignore_missing_imports enabled, even though the package will not install on anything below 3.10. In practice that means the formatter and the type checker are both aimed at an older Python than the one the code is allowed to run on. It is harmless today, and it would become a real problem the day the code uses syntax the older target cannot parse.

## Depending on an interface the upstream controls

The central risk of this package is structural, and it comes from what the package is not. ESPN controls the Fantasy API, its endpoints, its field names and its response shapes, and the package maps those onto Python objects. The README describes the supported sports as football and basketball, with NHL, MLB and WNBA in development, which tells you the mapping is per sport and under active construction. The library ships with an MIT licence, so you may use it in your own project as long as you keep the copyright and licence notice, and it is published on PyPI as espn_api. Two practical consequences follow. First, a change in the upstream response can break your code without any change in the package, so pinning a version of espn_api does not by itself protect you. Second, the README does not document how access to a private league is authenticated, only that private leagues are supported, so check that before designing around private league data. For the same reason, expect to use the debug output when something breaks: it is the only view of the contract you get.

## Conclusion

espn_api suits a developer who wants ESPN's fantasy numbers inside a script, a dashboard or a data pipeline, and who is prepared for the upstream interface to move under them. It is the wrong choice if you need a supported data contract, a written compatibility promise, or other sports right now, since only football and basketball are described as ready. Before you build on it, pin the version you tested, read the wiki for the endpoint detail the README leaves out, and confirm how a private league is authenticated, because the README does not explain that part.

## FAQ

### How do I install espn_api?

The released package installs with pip install espn_api. To work on the project itself, clone it with git, change into the espn-api directory and run uv sync, with uv sync --extra dev if you want the development tooling.

### Which sports does espn_api support?

Fantasy football and basketball are described as supported, with NHL, MLB and WNBA in development, and the README's usage example already imports hockey and baseball League classes alongside football and basketball.

### How do I see the raw ESPN API requests and responses?

Construct the League with debug=True, for example League(league_id=1245, year=2019, debug=True). The application prints all requests and the ESPN responses to the console, and the README suggests piping that output to a text file.

### Can I run the espn_api test suite without hitting the live ESPN API?

Yes. Run `uv run pytest tests --ignore-glob='**/integration/**'` to skip the tests that call the live ESPN API. Omitting the option runs everything, including those live calls.

## Sources

- [cwendt94/espn-api on GitHub](https://github.com/cwendt94/espn-api)
- [Issues](https://github.com/cwendt94/espn-api/issues)
- [License: MIT](https://github.com/cwendt94/espn-api/blob/master/LICENSE)
- [README](https://github.com/cwendt94/espn-api/blob/master/README.md)
- [Releases](https://github.com/cwendt94/espn-api/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/cwendt94-espn-api
