Factory Moduleο
Dynamic model generation for MLB StatsAPI endpoints.
This module provides a fully config-driven approach to generating endpoint classes and methods from JSON schemas, eliminating hardcoded model definitions.
Key features: - Dynamic class and method generation from JSON schemas - Response objects with URL metadata for caching - Configurable method exclusions - Automatic parameter validation from schemas
- class pymlb_statsapi.model.factory.APIResponse(response: Response, endpoint_name: str, method_name: str, path_params: dict | None = None, query_params: dict | None = None)[source]ο
Bases:
LogMixinMLB Stats API Response wrapper that includes URL metadata for caching and debugging.
This approach that just wraps the requests.Response and provides convenient access to URL components for cache key generation.
- __init__(response: Response, endpoint_name: str, method_name: str, path_params: dict | None = None, query_params: dict | None = None)[source]ο
- get_metadata() dict[source]ο
Get all request and response metadata as a JSON-serializable dict.
This includes everything about the request and response except the actual data payload. Consumers can use this metadata to build cache keys, store provenance, track API usage, etc.
- Returns:
- Metadata with the following structure:
request: Request metadata (endpoint, method, params, url, timestamp)
response: Response metadata (status_code, headers, elapsed, content_length)
- Return type:
Example
>>> response = StatsAPI.Schedule.schedule(sportId=1, date="2025-06-01") >>> metadata = response.get_metadata() >>> print(json.dumps(metadata, indent=2)) { "request": { "endpoint_name": "schedule", "method_name": "schedule", "path_params": {}, "query_params": {"sportId": "1", "date": "2025-06-01"}, "url": "https://statsapi.mlb.com/api/v1/schedule?sportId=1&date=2025-06-01", "scheme": "https", "domain": "statsapi.mlb.com", "path": "/api/v1/schedule", "http_method": "GET", "timestamp": "2025-01-15T10:30:00.123456+00:00" }, "response": { "status_code": 200, "ok": true, "elapsed_ms": 245.3, "content_type": "application/json", "content_length": 15234, "headers": {...} } }
- to_dict(include_data: bool = True) dict[source]ο
Convert the entire APIResponse to a JSON-serializable dict.
This is the primary method consumers should use to serialize the complete response (metadata + data) for storage, caching, or transmission.
- Parameters:
include_data β Whether to include the response data payload (default: True) Set to False to get only metadata (equivalent to get_metadata())
- Returns:
- Complete response with metadata and data:
metadata: All request/response metadata (from get_metadata())
data: The parsed JSON response data (if include_data=True)
- Return type:
Example
>>> response = StatsAPI.Schedule.schedule(sportId=1, date="2025-06-01") >>> # Get everything >>> full_dict = response.to_dict() >>> # Save to your storage >>> with open("my_cache.json", "w") as f: >>> json.dump(full_dict, f) >>> >>> # Or just metadata >>> metadata_only = response.to_dict(include_data=False)
- get_path(prefix: str = '') str[source]ο
Generate a resource path for this API response.
The path does NOT include file extensions - those are added by get_uri() for file/s3 protocols. This keeps the path protocol-agnostic and flexible.
Format: {prefix}/{endpoint}/{method}/{path_params}/{sorted_query_params}
Examples
schedule/schedule/sportId=1&date=2025-06-01
mlb-data/schedule/schedule/sportId=1&date=2025-06-01
game/liveGameV1/game_pk=12345/timecode=20250601_120000
- Parameters:
prefix β Optional prefix to prepend (separated by /)
- Returns:
Path string suitable for use across different storage protocols
- get_uri(prefix: str = '', gzip: bool = False) ParseResult[source]ο
Generate full file URI as a ParseResult for this API response.
Returns a urllib.parse.ParseResult that provides structured access to all URI components: - scheme: βfileβ - netloc: ββ (empty for file protocol) - path: the absolute file path
- Parameters:
prefix β Optional directory prefix
gzip β Whether to add .gz extension (default: False)
- Environment Variables:
- PYMLB_STATSAPI__BASE_FILE_PATH: Base directory for storage
(default: ./.var/local/mlb_statsapi)
- Returns:
ParseResult object with URI components. Call .geturl() to get string representation.
Examples
>>> result = response.get_uri(prefix="mlb-data") >>> result.scheme 'file' >>> result.path '/path/to/.var/local/mlb_statsapi/mlb-data/schedule/schedule/date=2025-06-01.json' >>> result.geturl() 'file:///path/to/.var/local/mlb_statsapi/mlb-data/schedule/schedule/date=2025-06-01.json'
>>> result = response.get_uri(gzip=True) >>> result.path '/path/to/.var/local/mlb_statsapi/schedule/schedule/date=2025-06-01.json.gz'
- save_json(file_path: str | None = None, gzip: bool = False, prefix: str = '') dict[source]ο
Save response JSON to a file.
- Parameters:
file_path β Path to save the JSON file. If None, auto-generates using get_uri().
gzip β Whether to gzip the output (default: False)
prefix β Optional directory prefix (only used if file_path is None)
- Returns:
Dict with βpathβ, βbytes_writtenβ, and βuriβ (ParseResult) keys
Examples
>>> # Save to explicit path >>> response.save_json("/path/to/file.json")
>>> # Auto-generate path >>> response.save_json(prefix="mlb-data")
>>> # Save gzipped with custom prefix >>> response.save_json(gzip=True, prefix="raw-data")
>>> # Get URI details when auto-generating >>> result = response.save_json(prefix="mlb-data") >>> result['path'] # String path >>> result['uri'].scheme # 'file' >>> result['uri'].geturl() # Full file:// URI
- gzip(file_path: str | None = None, prefix: str = '') dict[source]ο
Save response as gzipped JSON (convenience method).
This is equivalent to calling save_json(gzip=True, β¦).
- Parameters:
file_path β Path to save the gzipped JSON file. If None, auto-generates.
prefix β Optional directory prefix (only used if file_path is None)
- Returns:
Dict with βpathβ, βbytes_writtenβ, and βuriβ keys
Examples
>>> response.gzip("/path/to/file.json.gz") >>> response.gzip(prefix="mlb-data") # Auto-generates path
- class pymlb_statsapi.model.factory.EndpointMethod(endpoint_name: str, method_name: str, api_definition: dict, operation_definition: dict, config_path: str)[source]ο
Bases:
objectRepresents a single API method with its schema-defined parameters and validation.
- __init__(endpoint_name: str, method_name: str, api_definition: dict, operation_definition: dict, config_path: str)[source]ο
- get_schema() dict[source]ο
Get the original schema JSON that defines this method.
Returns a dict with: - api: The API definition (path, description) - operation: The operation definition (method, parameters, etc.) - endpoint: Endpoint name - method: Method name - config_path: Configured path (if different from schema)
- Returns:
Complete schema definition
- Return type:
Example
>>> method = api.Schedule.get_method_info("schedule") >>> schema = method.get_schema() >>> print(schema["operation"]["summary"]) 'View schedule info' >>> for param in schema["operation"]["parameters"]: ... print(f"{param['name']}: {param['description']}")
- get_parameter_schema(param_name: str) dict | None[source]ο
Get the full schema definition for a specific parameter.
- Parameters:
param_name β Name of the parameter (e.g., βsportIdβ, βdateβ)
- Returns:
dict with parameter details or None if not found
Example
>>> param = method.get_parameter_schema("sportId") >>> print(param["description"]) 'Top level organization of a sport' >>> print(param["required"]) False >>> print(param["type"]) 'integer'
- list_parameters() dict[source]ο
List all parameters with their types and whether theyβre required.
- Returns:
dict with βpathβ and βqueryβ keys, each containing parameter info
Example
>>> params = method.list_parameters() >>> for param in params["path"]: ... print(f"{param['name']} ({param['type']}): {param['required']}") >>> for param in params["query"]: ... print(f"{param['name']} ({param['type']}): {param['required']}")
- get_long_description() str[source]ο
Get a comprehensive description of this method including all schema details.
Returns a formatted string with: - Summary - Notes - HTTP method and path - All parameters with descriptions - Response information
- Returns:
Formatted description
- Return type:
Example
>>> print(method.get_long_description())
- validate_and_resolve_params(path_params: dict | None = None, query_params: dict | None = None) tuple[dict, dict, str][source]ο
Validate parameters and resolve the full URL path.
- Parameters:
path_params β Path parameter values
query_params β Query parameter values
- Returns:
Tuple of (validated_path_params, validated_query_params, resolved_path)
- Raises:
AssertionError β If required parameters are missing or invalid
- class pymlb_statsapi.model.factory.Endpoint(endpoint_name: str, schema: dict, endpoint_config: dict, excluded_methods: set[str] | None = None)[source]ο
Bases:
LogMixinDynamically generated endpoint class that creates methods from JSON schema.
- BASE_URL = 'https://statsapi.mlb.com/api'ο
- MAX_RETRIES = 3ο
- TIMEOUT = 30ο
- __init__(endpoint_name: str, schema: dict, endpoint_config: dict, excluded_methods: set[str] | None = None)[source]ο
- get_method(method_name: str) EndpointMethod[source]ο
Get the EndpointMethod object for introspection.
This allows access to all schema methods like: - get_schema() - get_parameter_schema() - list_parameters() - get_long_description()
- Parameters:
method_name β Name of the method
- Returns:
EndpointMethod instance
- Raises:
ValueError β If method not found
Example
>>> method = api.Schedule.get_method("schedule") >>> print(method.get_long_description()) >>> schema = method.get_schema() >>> param = method.get_parameter_schema("sportId")
- get_method_info(method_name: str) dict[source]ο
Get detailed information about a method.
DEPRECATED: Use get_method() instead for full schema access.
- Parameters:
method_name β Name of the method
- Returns:
dict with method details
Example
>>> info = api.Schedule.get_method_info("schedule") >>> print(info["path"]) >>> print(info["summary"])
- describe_method(method_name: str) str[source]ο
Get a human-readable description of a method with all its parameters.
This is a convenience wrapper around get_method().get_long_description().
- Parameters:
method_name β Name of the method
- Returns:
Formatted description
- Return type:
Example
>>> print(api.Schedule.describe_method("schedule"))