Retrieve baseball data in Python
Project description
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="2024-05-06", end_date="2024-05-06")
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="2024-05-06",
end_date="2024-05-06",
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=2024,
end_season=2024,
qual=100,
max_results=20,
)
print(df.head(10))
if __name__ == "__main__":
asyncio.run(main())
Examples
Runnable 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.
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.
Modules prefixed with _, including _schemas, are internal implementation details and are not part
of the compatibility contract.
Documentation
- Documentation
- API Use-Case Index: choose the right API by task.
Showcase
Projects using polars-baseball:
- MLB dashboard workflows
- Chinese baseball website data jobs
- Threads bot baseball data pipelines
Contributing
See CONTRIBUTING.md for development workflow and architecture notes.
Author
Created and maintained by Nick.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file polars_baseball-0.7.1.tar.gz.
File metadata
- Download URL: polars_baseball-0.7.1.tar.gz
- Upload date:
- Size: 117.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
362c8a4a03e878b3a00e78b97fa8e82700ec84a61b5579855b93362ee35d11c5
|
|
| MD5 |
9ded4dccdefb857198586cc8a17e8cff
|
|
| BLAKE2b-256 |
577aa18e42341accf2a20d805b339b84e1e1d8360f5fbf120e4b3cfd78cb86ed
|
Provenance
The following attestation bundles were made for polars_baseball-0.7.1.tar.gz:
Publisher:
python-publish.yml on nicko4o/polars-baseball
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
polars_baseball-0.7.1.tar.gz -
Subject digest:
362c8a4a03e878b3a00e78b97fa8e82700ec84a61b5579855b93362ee35d11c5 - Sigstore transparency entry: 2204866816
- Sigstore integration time:
-
Permalink:
nicko4o/polars-baseball@29503a1490b8e7cdf7a2e6df2dbae663dfdfec65 -
Branch / Tag:
refs/tags/v0.7.1 - Owner: https://github.com/nicko4o
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-publish.yml@29503a1490b8e7cdf7a2e6df2dbae663dfdfec65 -
Trigger Event:
release
-
Statement type:
File details
Details for the file polars_baseball-0.7.1-py3-none-any.whl.
File metadata
- Download URL: polars_baseball-0.7.1-py3-none-any.whl
- Upload date:
- Size: 148.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7fefae6abcacb04423bd9d933d39357d8714266b3ee6016bfaac262477c6afb5
|
|
| MD5 |
0f26f5c2736b9568eae0e120d441b535
|
|
| BLAKE2b-256 |
352e785f008ce9c3d9f44904f585c45480efd5573114fea0b6050ecb674d13fb
|
Provenance
The following attestation bundles were made for polars_baseball-0.7.1-py3-none-any.whl:
Publisher:
python-publish.yml on nicko4o/polars-baseball
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
polars_baseball-0.7.1-py3-none-any.whl -
Subject digest:
7fefae6abcacb04423bd9d933d39357d8714266b3ee6016bfaac262477c6afb5 - Sigstore transparency entry: 2204866827
- Sigstore integration time:
-
Permalink:
nicko4o/polars-baseball@29503a1490b8e7cdf7a2e6df2dbae663dfdfec65 -
Branch / Tag:
refs/tags/v0.7.1 - Owner: https://github.com/nicko4o
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-publish.yml@29503a1490b8e7cdf7a2e6df2dbae663dfdfec65 -
Trigger Event:
release
-
Statement type: