Skip to content

feat: add shared HTTP sessions and configurable timeouts - #258

Merged
Mattsface merged 1 commit into
release/0.8.0from
feat/shared-http-session
Aug 1, 2026
Merged

feat: add shared HTTP sessions and configurable timeouts#258
Mattsface merged 1 commit into
release/0.8.0from
feat/shared-http-session

Conversation

@Mattsface

@Mattsface Mattsface commented Aug 1, 2026

Copy link
Copy Markdown
Member

Why a shared session

Module-level requests.get() prevented connection reuse and made timeouts, session injection, and cleanup difficult. This change introduces one reusable requests.Session per Mlb client so HTTP connections can be pooled and request behavior can be configured without changing endpoint APIs.

How v1 and v1.1 share one session

Mlb creates or accepts exactly one session, then injects that same instance into both adapters:

Mlb
├── v1 adapter ────┐
│                  ├── one shared requests.Session
└── v1.1 adapter ──┘

Adapters that receive an injected session do not own it and will not close it.

Default timeout and overrides

Default timeout:

DEFAULT_TIMEOUT = (3.05, 30.0)  # connect, read

Every adapter request passes timeout= explicitly. Supported forms include:

Mlb(timeout=10)
Mlb(timeout=(3.05, 30.0))

The same forms are accepted by MlbDataAdapter.

Ownership rule

  • If the library creates the session, the library owns and closes it.
  • If the caller injects a session, the caller owns it and the library never closes it.

Sharing and ownership are separate: both adapters share the session, but neither owns a session injected by Mlb.

Cleanup and context manager

  • Mlb.close() and MlbDataAdapter.close() close library-owned sessions at most once and are safe to call repeatedly.
  • Injected sessions are left open.
  • with Mlb() as mlb: returns the client from __enter__ and calls close() from __exit__, including when the block exits due to an exception. Exceptions are not suppressed.

Compatibility

Existing positional constructors remain valid:

Mlb()
Mlb("statsapi.mlb.com")
Mlb("statsapi.mlb.com", logger)

MlbDataAdapter()
MlbDataAdapter("statsapi.mlb.com")
MlbDataAdapter("statsapi.mlb.com", "v1.1")
MlbDataAdapter("statsapi.mlb.com", "v1.1", logger)

Unchanged behavior

  • Endpoint method signatures and return types
  • MlbResult behavior
  • HTTP response classification and 404 empty-data semantics
  • Existing exception messages / public exception hierarchy
  • Synchronous client API

Intentionally not included

  • Retries / backoff / Retry-After
  • New exception subclasses
  • Async support, caching, rate limiting
  • Endpoint redesign or package version / publishing changes

Tests

poetry run pytest tests/test_mlb_session.py -v
# 31 passed

poetry run pytest tests/test_mlb_dataadapter.py tests/test_mlb_result.py -v
# 26 passed

poetry run pytest tests/ --ignore=tests/external_tests
# 126 passed

poetry run pytest tests/external_tests/mlbdataadapter/test_mlbadapter.py -v
# 3 passed

Live MLB adapter tests succeeded; no external outage observed.

Open in Web Open in Cursor 

@Mattsface
Mattsface marked this pull request as ready for review August 1, 2026 05:49

@Mattsface Mattsface left a comment

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good. thumbs up

@Mattsface
Mattsface merged commit 6c4db03 into release/0.8.0 Aug 1, 2026
3 checks passed
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