Skip to content

Implement AsyncMlb vertical slice #303

Description

@Mattsface

Parent: #297
Depends on: #299, #301, #302

Goal

Add the first public AsyncMlb client with a deliberately small set of representative endpoints to prove the end-to-end architecture before expanding coverage.

Initial scope

Implement AsyncMlb with:

  • public root import: from mlbstatsapi import AsyncMlb
  • constructor shape aligned with Define the v1.1 async API and transport contract #298
  • async with AsyncMlb() support
  • explicit aclose()
  • shared async transport lifecycle
  • existing strict/compatibility settings from the async contract
  • initial endpoints:
    • get_team
    • get_person
    • get_schedule

Contract requirements from #298

Public API

  • AsyncMlb is a stable public 1.x API
  • Public async endpoint names/signatures become compatibility commitments once released
  • Existing synchronous Mlb behavior and signatures remain unchanged
  • Return the same existing Pydantic/domain models as sync equivalents
  • Preserve the same None, [], and {} behavior for equivalent responses

Constructor and lifecycle

Public shape should mirror sync as closely as practical:

AsyncMlb(
    hostname="statsapi.mlb.com",
    logger=None,
    timeout=DEFAULT_TIMEOUT,
    client=None,
    *,
    strict_http=True,
)
  • async with returns the AsyncMlb instance
  • __aexit__() awaits aclose()
  • aclose() is idempotent and closes only library-owned async transport
  • Caller-injected clients remain caller-owned and open
  • Cleanup must preserve original exceptions and cancellation

Endpoint behavior

For get_team, get_person, and get_schedule:

Concurrency

  • One AsyncMlb instance supports multiple concurrent in-flight endpoint calls on the same event loop
  • Concurrency remains caller-controlled
  • Endpoint methods do not introduce hidden fan-out, detached tasks, worker pools, or unrelated background work
  • Per-request state remains independent
  • Caller-created in-flight operations must finish before the client is closed

Design requirement

Do not duplicate parsing/model-construction logic when a shared helper from #299 can be used.

Transport-specific implementation details must remain behind AsyncMlbDataAdapter rather than leaking into the public AsyncMlb API.

Acceptance criteria

  • AsyncMlb is importable from mlbstatsapi
  • Constructor/lifecycle behavior matches Define the v1.1 async API and transport contract #298
  • async with correctly cleans up library-owned resources
  • Explicit aclose() is idempotent and safe
  • get_team, get_person, and get_schedule work end to end
  • Returned models and empty-result behavior match sync equivalents
  • Initial endpoints reuse shared parsing/model construction
  • Same-client concurrent endpoint calls work on one event loop
  • Endpoint calls do not introduce hidden fan-out/background work
  • Existing Mlb behavior and signatures remain unchanged
  • Initial public async usage has deterministic tests

Refs #297
Contract: #298

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions