Skip to main content

Retrieve baseball data in Python

Project description

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="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/:

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

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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

polars_baseball-0.7.3.tar.gz (117.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

polars_baseball-0.7.3-py3-none-any.whl (148.8 kB view details)

Uploaded Python 3

File details

Details for the file polars_baseball-0.7.3.tar.gz.

File metadata

  • Download URL: polars_baseball-0.7.3.tar.gz
  • Upload date:
  • Size: 117.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for polars_baseball-0.7.3.tar.gz
Algorithm Hash digest
SHA256 b1e6965839da10da99bce2ac3531a01b2ef3dd57940a579507ce9f28b1abe79e
MD5 1f16a437c102b23039d5f9c0019a5a38
BLAKE2b-256 507bf2dba3571181331eef7a69f83201d1ac6b89e82afe16a5b2678f82c9342f

See more details on using hashes here.

Provenance

The following attestation bundles were made for polars_baseball-0.7.3.tar.gz:

Publisher: python-publish.yml on nicko4o/polars-baseball

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file polars_baseball-0.7.3-py3-none-any.whl.

File metadata

  • Download URL: polars_baseball-0.7.3-py3-none-any.whl
  • Upload date:
  • Size: 148.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for polars_baseball-0.7.3-py3-none-any.whl
Algorithm Hash digest
SHA256 4780f6fd655cd589bce3109694261bd24ba13e41ad31ac1a86481b6ae516b407
MD5 5ff3e8d1199f9068f677aeddf2ba8902
BLAKE2b-256 e0a1b6511f3803f55c2e70075e68b98d90f4fe99d97f215104747ded1945668e

See more details on using hashes here.

Provenance

The following attestation bundles were made for polars_baseball-0.7.3-py3-none-any.whl:

Publisher: python-publish.yml on nicko4o/polars-baseball

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page