Skip to content

Add a versioned User-Agent - #279

Merged
Mattsface merged 1 commit into
release/0.9.0from
feat/versioned-user-agent
Aug 3, 2026
Merged

Add a versioned User-Agent#279
Mattsface merged 1 commit into
release/0.9.0from
feat/versioned-user-agent

Conversation

@Mattsface

Copy link
Copy Markdown
Member

Closes #271
Refs #265

Summary

  • adds a package and version User-Agent to library-created Sessions
  • reads the installed version from package metadata
  • preserves other Requests default headers
  • leaves all caller-injected Session headers untouched
  • preserves retry, strict-mode, and Session ownership behavior
  • adds offline coverage for outgoing prepared requests

Why

Requests sends its generic python-requests/<version> User-Agent by default, so MLB Stats API traffic from this package is indistinguishable from any other Requests-based client. A package-specific, versioned User-Agent makes package traffic identifiable while debugging and makes the installed release visible without any extra request data.

What changed

mlbstatsapi/mlb_dataadapter.py gains one internal source of truth for library-owned Session setup:

  • PACKAGE_DISTRIBUTION_NAME = "python-mlb-statsapi" is the only place the distribution name is stored.
  • _build_user_agent() reads the version through importlib.metadata.version() and falls back to unknown on PackageNotFoundError, so it cannot raise during Session construction.
  • _configure_library_session() sets session.headers["User-Agent"] and then calls the existing _configure_retry_adapters().

MlbDataAdapter.__init__ and Mlb.__init__ now call _configure_library_session() in the branch that already handled session is None. Injected Sessions take exactly the same path as before and are never passed to the helper.

The package version is not duplicated in source. pyproject.toml is unchanged, and the header will automatically reflect the version bump made by the release-preparation issue. Nothing new is exported from mlbstatsapi/__init__.py.

Behavior

Session origin User-Agent Other headers Adapters
Library-created python-mlb-statsapi/<installed-version> Requests defaults preserved Library retry policy
Caller-injected Caller-controlled Untouched Caller-controlled

Only the User-Agent key is assigned; the header mapping is never replaced, so Accept-Encoding, Accept, and Connection keep their Requests default values.

Tests

New coverage in tests/test_mlb_session.py, all offline:

  • the version comes from patched package metadata (9.8.7python-mlb-statsapi/9.8.7), which proves no release string is hardcoded
  • Mlb() and standalone MlbDataAdapter() Sessions both carry the versioned header
  • a prepared request built with session.prepare_request() carries the header, with no request sent
  • every non-User-Agent Requests default header matches a baseline requests.Session(), plus explicit checks for Accept-Encoding, Accept, and Connection
  • an injected my-baseball-project/1.0 User-Agent and an X-Application: scoreboard header stay unchanged through construction and close(), for both Mlb and MlbDataAdapter
  • PackageNotFoundError yields python-mlb-statsapi/unknown and does not raise
  • the mounted retry adapters still satisfy assert_library_retry_policy() after the header is set

The existing test_injected_session_is_not_replaced_with_library_session already asserts the Session identity contract across both adapters, so it was left as-is rather than duplicated.

Documentation

docs/http-transport.md gains a ## User-Agent section covering the header format, the metadata source, preserved default headers, the untouched injected-Session rule, the unknown fallback, an injected-Session example, and an explicit statement that this is not telemetry and carries no machine or user identifiers. The compatibility-warning documentation was not modified.

Validation

  • poetry run pytest tests/test_mlb_session.py -v — 45 passed
  • poetry run pytest tests/test_mlb_retries.py -v
  • poetry run pytest tests/test_http_contract.py -v
  • poetry run pytest tests/test_mlb_exceptions.py -v
  • poetry run pytest tests/ --ignore=tests/external_tests -v — 255 passed
  • git diff --check

tests/test_http_warnings.py does not exist on release/0.9.0 yet, so the issue #270 warning suite was not run here.

Risk

Low. The only behavior change is one header value on Sessions the library creates itself. No public method, argument, return type, exception, or endpoint behavior changed, and no new runtime dependency was added (importlib.metadata is standard library).

Possible impact: any consumer asserting on the outgoing User-Agent of a library-created Session will now see python-mlb-statsapi/<version> instead of python-requests/<version>.

Intentionally left out

  • compatibility warnings and MlbHttpCompatibilityWarning work from Add warnings for future strict HTTP behavior #270, which this branch does not depend on
  • the pyproject.toml version bump, which belongs to release preparation
  • any machine identifiers, hostnames, OS or hardware details, request identifiers, application-name discovery, telemetry, or analytics
  • exporting the internal User-Agent helper, since no new public API is required

Base branch

release/0.9.0

Open in Web Open in Cursor 

Co-authored-by: Matthew Spah <spahmatthew@gmail.com>
@Mattsface
Mattsface marked this pull request as ready for review August 3, 2026 23:24
@Mattsface
Mattsface merged commit 4ca2e80 into release/0.9.0 Aug 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants