Skip to main content

polars-baseball

PyPI version Python versions 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 context: 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:
    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/:

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

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

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.

Release files for polars-baseball 0.16.1

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.16.1
File Size Uploaded
polars_baseball-0.16.1.tar.gz 118.6 kB Details

Built distribution (wheel)

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

Total release size: 269.1 kB

Release files / polars_baseball-0.16.1.tar.gz

Download URL polars_baseball-0.16.1.tar.gz
Size 118.6 kB
Tags Source
SHA-256 checksum
How to use checksums
fd9561cb1af6cebf40119860e201e09206d92a5d8fc50882cd89d05823052160
BLAKE2b-256 checksum
How to use checksums
7ce756573bb1103a09a5ffd83e78c43bd08ddc9b4e91e4593e4a1588d369cbd7
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 4, 2026.

Transparency log

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

Download URL polars_baseball-0.16.1-py3-none-any.whl
Size 150.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
8a24cb4266f055cba46cc56419b165342ee54f48f49074fbcb706eed7e50e4e3
BLAKE2b-256 checksum
How to use checksums
9442ca880efec33c296cb7d48e9d0efa2a92b9d77f4644cf386372cebab1ba12
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 4, 2026.

Transparency log

Release history Release notifications | RSS feed

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

This release

0.16.1 This release

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