Skip to content

python-mlb-statsapi 1.0.0

Version 1.0.0 is the stable HTTP contract release.

Version 0.8.0 made the network layer reliable. Version 0.9.0 made HTTP behavior configurable and introduced a warning-backed migration path toward stricter failures. Version 1.0.0 completes that migration: strict HTTP handling is now the default, while an explicit compatibility opt-out remains available for callers who need more time to migrate.

The primary breaking change is that Mlb() and MlbDataAdapter() now default to strict_http=True. A final non-404 4xx response raises MlbHttpError instead of returning the historical empty result.

Endpoint-specific 404 behavior, Session ownership, retry values, structured exceptions, and the synchronous public client remain unchanged.

Breaking change

Strict HTTP behavior is now the default

In version 0.9.x, these constructions were equivalent and kept compatibility mode:

import mlbstatsapi

mlb = mlbstatsapi.Mlb()
mlb = mlbstatsapi.Mlb(strict_http=False)

In version 1.0.0, the default matches explicit strict handling:

import mlbstatsapi

mlb = mlbstatsapi.Mlb()
mlb = mlbstatsapi.Mlb(strict_http=True)

Default behavior for a final response:

Successful 2xx
    Return the normal endpoint result

Final non-404 4xx
    Raise MlbHttpError

404
    Preserve endpoint-specific None, [], or {} behavior

Final 5xx
    Raise MlbHttpError

Timeout
    Raise MlbTimeoutError

Transport failure
    Raise MlbTransportError

Successful invalid JSON
    Raise MlbDecodeError

"Final" means the response remaining after the bounded retry policy has completed.

Highlights

Endpoint-specific 404 behavior is preserved

A 404 still follows the existing per-endpoint contract. Depending on the endpoint, a missing resource may return:

None
[]
{}

Not every 404 raises MlbHttpError. The strict default does not change that.

Explicit compatibility mode remains available

Callers who need the historical empty-result path can opt out temporarily:

import mlbstatsapi

with mlbstatsapi.Mlb(strict_http=False) as mlb:
    player = mlb.get_person(664034)

Compatibility mode:

  • Preserves the historical empty result for final non-404 4xx responses
  • Emits MlbHttpCompatibilityWarning exactly once per suppressed final response
  • Does not change 404 behavior
  • Does not suppress final 5xx errors
  • Does not alter timeout, transport, or decode failures
  • Runs only after retry exhaustion

It is a temporary migration opt-out and an explicit request for historical 0.9 behavior. It is not the recommended long-term 1.0 configuration.

Compatibility warnings point to the public caller frame outside the package namespace. Messages include the status code and request URL, state that strict_http=False selected compatibility mode, note that the historical empty result was returned, identify strict handling as the version 1.0 default, and explain how to receive MlbHttpError instead. Response bodies, headers, credentials, cookies, and tokens are never included.

Stable public API contract

Version 1.0.0 establishes the stable public API contract documented in public-api.md. That document is the authoritative classification for package-root imports, constructor signatures, the exception hierarchy, Session ownership, documented endpoint methods, Python support, and internal or private APIs.

This release does not freeze every upstream MLB response field, every class under mlbstatsapi.models, or private underscore-prefixed names, and it does not promise that the unofficial MLB API itself will never change.

Session ownership remains explicit

Library-created Session
    Configured and closed by the library
    Receives retry adapters
    Receives the package User-Agent

Caller-injected Session
    Configured and closed by the caller
    Existing adapters remain untouched
    Existing headers remain untouched

Ownership rules are unchanged from versions 0.8.0 and 0.9.0. The new strict default does not change Session creation, injection, or cleanup behavior.

Retry behavior remains bounded

Library-created Sessions continue to retry temporary GET failures for:

429
500
502
503
504
Initial request: 1
Maximum retries: 3
Maximum total attempts: 4
Backoff factor: 0.5
Retry-After respected: yes

Retry values are unchanged. Ordinary client errors such as 400, 401, 403, and 404 are not retried. Invalid JSON and Pydantic validation failures are not retried. The new strict default is evaluated only after retries are exhausted.

Structured exceptions

The exception hierarchy is unchanged:

TheMlbStatsApiException
├── MlbTransportError
│   └── MlbTimeoutError
├── MlbHttpError
└── MlbDecodeError

MlbHttpError continues to expose method, status_code, reason, url, response_data, and body_excerpt. Broad catches of TheMlbStatsApiException remain valid.

Testing and release validation

Deterministic offline coverage documents the version 1.0 HTTP contract, including the strict default, explicit compatibility mode, warning behavior, 404 return shapes, Session ownership, and retry exhaustion.

scripts/validate_release.py is the packaging check for the built artifacts. It clean-installs the wheel and the source distribution into separate throwaway virtual environments and runs the same installed-package smoke test against each, so a broken sdist build, a missing runtime dependency, or an omitted package file cannot hide behind a working wheel.

Against the installed artifact the smoke test verifies:

Declared metadata matches the built version
Supported package-root imports resolve
Strict HTTP handling is the default for Mlb() and MlbDataAdapter()
A final 403 raises MlbHttpError with status, reason, method, URL, and payload
strict_http=False returns the historical empty result and warns exactly once
A library-created Session carries the versioned User-Agent and retry policy
A caller-injected Session keeps its headers, adapters, and ownership

Every response the smoke test observes is produced by an injected fake Session, so release validation never contacts the MLB API. Continuous integration builds the artifacts, runs the validator, and runs twine check on both artifacts. No ordinary pull request or push path publishes anything.

Python support

Claim Value
Minimum declared Python version (Requires-Python) >=3.10
CI-validated versions 3.10, 3.11, 3.12, 3.13, 3.14

The minimum declared Python version is 3.10 and the CI-validated versions are 3.10 through 3.14. Version 1.0.0 adds no upper Python bound and does not change the declared runtime requirement. Prerelease interpreters are excluded from the required matrix and are not claimed as supported.

Migration guidance

Recommended process when upgrading from 0.9.x:

  1. Identify code that relied on empty results for failed non-404 4xx responses
  2. Add handling for MlbHttpError
  3. Distinguish 404 domain results from other HTTP failures
  4. Use strict_http=False only where migration cannot happen immediately
  5. Test warning-as-error configurations
  6. Remove strict_http=False
  7. Confirm injected Session and retry behavior remain correct

Version 0.9-style temporary compatibility:

import mlbstatsapi

with mlbstatsapi.Mlb(strict_http=False) as mlb:
    player = mlb.get_person(664034)

Recommended 1.0 state:

import mlbstatsapi

try:
    with mlbstatsapi.Mlb() as mlb:
        player = mlb.get_person(664034)
except mlbstatsapi.MlbHttpError as exc:
    print(exc.status_code)
    print(exc.url)

A missing person may still return None on a 404 and is not necessarily an exception.

Applications that treat warnings as exceptions should prefer removing strict_http=False and catching MlbHttpError. A temporary targeted filter on MlbHttpCompatibilityWarning is acceptable during migration; disabling every warning or every FutureWarning is not recommended.

Documentation

Not included

Version 1.0.0 does not add:

  • Async support
  • Response caching
  • New MLB endpoints
  • Global rate limiting
  • Strict handling for endpoint-specific 404 responses
  • Automatic modification of injected Sessions
  • Telemetry
  • New retry values