Skip to main content

polars-baseball

PyPI version Python versions Documentation CI Codecov License Downloads

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.DataFrame unless an API reference explicitly documents a non-tabular contract.
  • Async-first engine: Data-fetching APIs are async def and 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 client: BaseballClient (or BaseballContext) lets long-running apps control HTTP and cache resources explicitly.
  • Explicit HTTP policy: HttpClient exposes 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:
    lf = await pb.savant.statcast(start_date="2026-06-01", end_date="2026-06-01")
    df = lf.collect()
    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:
    lf = await pb.savant.pitcher(
        start_date="2026-06-01",
        end_date="2026-06-01",
        # Use pb.lookup.playerid_lookup("Judge", "Aaron") to find player IDs
        player_id=506433,
    )
    df = lf.collect()
    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/:

Notebooks (interactive)

Interactive Jupyter notebooks live in notebooks/:

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

Long-running concurrent services should manage their own BaseballClient (or BaseballContext) and pass it into API calls for explicit resource and connection pool management:

from contextlib import asynccontextmanager

from fastapi import FastAPI

import polars_baseball as pb


@asynccontextmanager
async def lifespan(app: FastAPI):
    async with pb.BaseballClient() as client:
        app.state.pb_client = client
        yield


app = FastAPI(lifespan=lifespan)


@app.get("/statcast")
async def get_statcast() -> dict[str, int]:
    lf = await pb.savant.statcast(
        start_date="2026-06-01",
        end_date="2026-06-02",
        context=app.state.pb_client,
    )
    df = lf.collect()
    return {"rows": df.height}

API Namespace Policy

The package root (import polars_baseball as pb) exposes provider namespaces (pb.savant, pb.fangraphs, pb.bref, pb.mlb, pb.retrosheet, pb.lahman, pb.lookup), client classes (pb.BaseballClient, pb.BaseballContext), and universal enums (Position, KeyType).

Provider-specific workflows and enums live in their dedicated namespaces (e.g. pb.fangraphs.*, pb.mlb.*). Modules prefixed with _, including _schemas, are internal implementation details and are not part of the compatibility contract.

Documentation & Resources

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:

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.

Metadata

Release files for polars-baseball 0.25.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for polars-baseball 0.25.0
File Size Uploaded
polars_baseball-0.25.0.tar.gz 133.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for polars-baseball 0.25.0
File Interpreter ABI Platform
polars_baseball-0.25.0-py3-none-any.whl Python 3 none any Details

Total release size: 304.2 kB

Release files / polars_baseball-0.25.0.tar.gz

Download URL polars_baseball-0.25.0.tar.gz
Size 133.9 kB
Tags Source
SHA-256 checksum
How to use checksums
d72b6769005bb85022aacd03bb77d29fa99f1971963eb30ea826b1d161b67da4
BLAKE2b-256 checksum
How to use checksums
6079e6afad5fbef11623adb4af14f3d62d562ef2d1c45dace8f66a2210635cad
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 Oct 14, 2026.

Transparency log

Release files / polars_baseball-0.25.0-py3-none-any.whl

Download URL polars_baseball-0.25.0-py3-none-any.whl
Size 170.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
e025a9adaba31d0a7a61f0dedcfd90358355f0a59409706496791e643fbaaa82
BLAKE2b-256 checksum
How to use checksums
199d3a98749eed3e34859c527bc679cf5a3f5d4fc6311304e3dc776e7269db9b
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 Oct 14, 2026.

Transparency log

Release history Release notifications | RSS feed

0.26.0

2 release files

This release

0.25.0 This release

2 release files

0.22.0

2 release files

0.21.1

2 release files

0.21.0

2 release files

0.20.2

2 release files

0.20.1

2 release files

0.20.0

2 release files

0.19.1

2 release files

0.19.0

2 release files

0.18.0

2 release files

0.17.0

2 release files

0.13.1

2 release files

0.13.0

2 release files

0.12.0

2 release files

0.11.0

2 release files

0.10.0

2 release files

0.9.0

2 release files

0.8.1

2 release files

0.8.0

2 release files

0.7.6

2 release files

0.7.5

2 release files

0.7.4

2 release files

0.7.3

2 release files

0.7.2

2 release files

0.7.1

2 release files

0.7.0

2 release files

0.6.1

2 release files

0.6.0

2 release files

0.5.0

2 release files

0.4.0

2 release files

0.3.0

2 release files

0.2.0

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page