polars-baseball
Languages: English | Traditional Chinese
polars-baseball is The unified Polars-native baseball data SDK: a typed, async-first Python
library for retrieving MLB and baseball analytics data from Statcast, Baseball Savant, FanGraphs,
Baseball Reference, Lahman, Retrosheet, and the MLB Stats API.
If you searched for python baseball data, python statcast, fangraphs python,
baseball savant api, pybaseball alternative, or polars dataframe baseball, this project is
built for the workflow where data should land directly in polars.DataFrame instead of going
through pandas first.
Why use polars-baseball instead of pybaseball?
pybaseball is useful and established. polars-baseball is aimed at a different execution model:
async data ingestion, native Polars output, and one consistent entry point across multiple baseball
data providers.
| Feature | pybaseball | polars-baseball |
|---|---|---|
| Polars native | No | Yes |
| Async data fetching | No | Yes |
| Statcast / Baseball Savant | Yes | Yes |
| FanGraphs | Yes | Yes |
| MLB Stats API | Limited | Yes |
| Lahman / Retrosheet workflows | Partial | Yes |
| Built-in cache | Partial | Yes |
| Typed public API | Partial | Yes |
Typical pandas-first workflow:
pybaseball -> pandas -> convert to Polars -> analysis
polars-baseball workflow:
polars-baseball -> Polars -> analysis
Key Features
- Polars-native data: Public data-fetching APIs return
polars.DataFrameunless an API reference explicitly documents a non-tabular contract. - Async-first engine: Data-fetching APIs are
async defand can be composed with your own async workflows. - Multiple providers: Statcast, Baseball Savant, FanGraphs, Baseball Reference, Lahman, Retrosheet, MLB Stats API, and player ID workflows.
- Opt-in file cache: Large workflows can cache repeated network requests as Parquet files.
- Service-ready context:
BaseballContextlets long-running apps control HTTP and cache resources explicitly. - Explicit HTTP policy:
HttpClientexposes timeout, retry, and BRef rate-limit settings.
Installation
pip install polars-baseball
For local development:
git clone https://github.com/nicko4o/polars-baseball
cd polars-baseball
uv sync --all-extras
To run visualization examples:
pip install "polars-baseball[plot]"
Quick Start
Statcast pitch-level data
import asyncio
import polars_baseball as pb
async def main() -> None:
df = await pb.statcast(start_date="2026-06-01", end_date="2026-06-01")
print(df.head(5))
if __name__ == "__main__":
asyncio.run(main())
Aggregate directly with Polars
import asyncio
import polars as pl
import polars_baseball as pb
async def main() -> None:
df = await pb.statcast_pitcher(
start_date="2026-06-01",
end_date="2026-06-01",
# Use pb.playerid_lookup("Judge", "Aaron") to find player IDs
player_id=506433,
)
summary = df.group_by("pitch_type").agg(
pl.col("release_speed").mean().alias("mean_speed"),
pl.len().alias("pitch_count"),
)
print(summary.sort("pitch_count", descending=True))
if __name__ == "__main__":
asyncio.run(main())
FanGraphs leaderboard
import asyncio
import polars_baseball as pb
async def main() -> None:
df = await pb.fangraphs.batting(
start_season=2026,
end_season=2026,
qual=100,
max_results=20,
)
print(df.head(10))
if __name__ == "__main__":
asyncio.run(main())
Examples
Scripts (CLI-ready)
Runnable .py examples live in examples/:
examples/statcast_pitch_mix.py: Statcast pitch mix with Polars.examples/fangraphs_leaderboard.py: FanGraphs batting leaderboard.examples/mlb_schedule.py: MLB Stats API schedule query.
Notebooks (interactive)
Interactive Jupyter notebooks live in notebooks/:
notebooks/statcast_pitch_mix_demo.ipynb: Statcast pitch mix, velocity leaders, batted-ball outcomes.notebooks/fangraphs_leaderboard_demo.ipynb: FanGraphs batting leaderboard with sabermetric filters.notebooks/mlb_schedule_demo.ipynb: MLB schedule, standings, rosters, and team metadata.
Benchmarking
Do not trust performance claims without a reproducible command:
python -m benchmarks run statcast_1week
List available profiles:
python -m benchmarks run list
Full command reference:
python -m benchmarks run <profile> [--json] [--json-file PATH] [--baseline] [--fail-if-regression]
python -m benchmarks baseline show
python -m benchmarks baseline clear
The runner reports wall time, CPU time, peak Python memory (via tracemalloc), GC collections,
and result shape. Use the --baseline flag to save results and compare against historical data.
Use the same date range, cache state, Python version, and machine when comparing
against pandas-first workflows.
Web Services & Concurrency
Calling package functions without context uses the implicit package-level BaseballContext.
That default context is convenient for scripts and does not write cache files unless
configure_cache() has been called. Long-running concurrent services should manage their own
context and pass it into every API call.
from contextlib import asynccontextmanager
from fastapi import FastAPI
import polars_baseball as pb
@asynccontextmanager
async def lifespan(app: FastAPI):
async with pb.BaseballContext() as context:
app.state.pb_context = context
yield
app = FastAPI(lifespan=lifespan)
@app.get("/statcast")
async def get_statcast() -> dict[str, int]:
df = await pb.statcast(
start_date="2026-06-01",
end_date="2026-06-02",
context=app.state.pb_context,
)
return {"rows": df.height}
API Namespace Policy
The package root (import polars_baseball as pb) exposes core convenience APIs and provider
namespaces. Use pb.fangraphs, pb.savant, and pb.mlb for provider-specific workflows.
Lahman, Retrosheet, Baseball Reference, and player ID workflows remain available from the package root.
Typed enums such as Position, MlbStatsGroup, MlbRosterType, FangraphsStatsCategory,
FangraphsMonth, FangraphsLeague, FangraphsPositions, and FangraphsStatColumn are exported from
the package root for use in typed parameters.
Modules prefixed with _, including _schemas, are internal implementation details and are not part
of the compatibility contract.
Documentation & Resources
- Official Documentation Portal
- API Use-Case Index: Choose the right API by task.
- Maintaining Guide: Package publishing and maintenance steps.
Showcase
Projects using polars-baseball:
- MLB dashboard workflows
- Chinese baseball website data jobs
- Threads bot baseball data pipelines
Community & Governance
We welcome contributions! Please review our repository policies before submitting PRs or issues:
- Contributing Guidelines (Includes AI-Assisted Contribution Policy)
- Code of Conduct
- Security Policy
Data Attribution & Copyright Notices
polars-baseball is a data retrieval library and does not claim ownership of upstream datasets:
- Retrosheet: The information used here was obtained free of charge from and is copyrighted by Retrosheet. Interested parties may contact Retrosheet at www.retrosheet.org.
- Statcast & MLB Stats API: Data provided courtesy of Major League Baseball / Baseball Savant.
- FanGraphs & Baseball Reference: Data provided courtesy of FanGraphs and Baseball Reference. Please respect upstream terms of service and rate limits.
- Lahman: Lahman's Baseball Database by Sean Lahman.
Citation
If you use polars-baseball in research, academic work, or software projects, please cite it using CITATION.cff.
Author
Created and maintained by Nick.
License
This project is licensed under the MIT License.
Release files for polars-baseball 0.19.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| polars_baseball-0.19.1.tar.gz | 128.1 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| polars_baseball-0.19.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 289.7 kB
Release files / polars_baseball-0.19.1.tar.gz
| Download URL | polars_baseball-0.19.1.tar.gz |
|---|---|
| Size | 128.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
20f5b504e614d2ab28dedb3312824cdf2e3637d6e3370ed423552ff23826ecb3
|
|
BLAKE2b-256 checksum How to use checksums |
fbfeebc909c970447a450545f4d255c8ec8bb14ff40805c8c65ea42b60c30d0c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 14, 2026.
Transparency logRelease files / polars_baseball-0.19.1-py3-none-any.whl
| Download URL | polars_baseball-0.19.1-py3-none-any.whl |
|---|---|
| Size | 161.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
1cf11579d45956fe15ace016ef376e4db67a7eabdbee9b5cfaf2aaa69ded565e
|
|
BLAKE2b-256 checksum How to use checksums |
d776f703dd24ad8e5df449a5b7c405eb20b12950b62d038bf096a716062a05a4
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 14, 2026.
Transparency log