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.
  • Built-in cache: Repeated network requests are cached as Parquet files for large workflows.
  • Service-ready context: BaseballContext lets long-running apps control HTTP and cache resources explicitly.

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_dt="2024-05-06", end_dt="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_dt="2024-05-06",
        end_dt="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:
    request = pb.FanGraphsRequest.batting(
        start_season=2024,
        end_season=2024,
        qual=100,
        max_results=20,
    )
    df = await pb.fg_data(request)
    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. Start with:

python examples/benchmark_statcast.py --start-date 2024-04-01 --end-date 2024-04-07

The script reports row count, column count, wall time, and Python allocation peak measured by tracemalloc. 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, but 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_dt="2026-06-01",
        end_dt="2026-06-02",
        context=app.state.pb_context,
    )
    return {"rows": df.height}

API Namespace Policy

The package root (import polars_baseball as pb) exposes stable public APIs, including provider specific data functions such as Lahman, Retrosheet, Baseball Reference, and player ID workflows.

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.2.0.tar.gz (107.5 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.2.0-py3-none-any.whl (135.4 kB view details)

Uploaded Python 3

File details

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

File metadata

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

File hashes

Hashes for polars_baseball-0.2.0.tar.gz
Algorithm Hash digest
SHA256 9e4912fe18a0e8784cda987775f67b209aca10cb42b2c89be7528e12ce8836fe
MD5 bbf358c38d396064c50b3e3994d6330a
BLAKE2b-256 e0b45fef84baef88fcd7cedc4851c81fb2d82c77f135e9ad4cdf5b62f54f161b

See more details on using hashes here.

Provenance

The following attestation bundles were made for polars_baseball-0.2.0.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.2.0-py3-none-any.whl.

File metadata

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

File hashes

Hashes for polars_baseball-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 3f7c54d7cc0d877cbb3e622020c104a8b5701951ea2dd5a315424914fd84a0db
MD5 f95753aeb97a2bec511ee09ac916637d
BLAKE2b-256 03f07a2f5f7e85ed08c0e00f8847a78a95eae13c232459a907863078d0e382c3

See more details on using hashes here.

Provenance

The following attestation bundles were made for polars_baseball-0.2.0-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