baseball-api-wrapper 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- baseball_api_wrapper/__init__.py +32 -0
- baseball_api_wrapper/client.py +86 -0
- baseball_api_wrapper/modules/__init__.py +0 -0
- baseball_api_wrapper/modules/games.py +147 -0
- baseball_api_wrapper/modules/players.py +178 -0
- baseball_api_wrapper/modules/roster.py +164 -0
- baseball_api_wrapper/modules/teams.py +142 -0
- baseball_api_wrapper-0.1.0.dist-info/METADATA +102 -0
- baseball_api_wrapper-0.1.0.dist-info/RECORD +12 -0
- baseball_api_wrapper-0.1.0.dist-info/WHEEL +5 -0
- baseball_api_wrapper-0.1.0.dist-info/licenses/LICENSE +21 -0
- baseball_api_wrapper-0.1.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"""
|
|
2
|
+
baseball_api_wrapper
|
|
3
|
+
====================
|
|
4
|
+
A Python wrapper for the official MLB Stats API (https://statsapi.mlb.com).
|
|
5
|
+
|
|
6
|
+
Quick start::
|
|
7
|
+
|
|
8
|
+
from baseball_api_wrapper import get_teams
|
|
9
|
+
|
|
10
|
+
teams = get_teams(2024)
|
|
11
|
+
for team in teams:
|
|
12
|
+
print(team["id"], team["name"])
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
from .client import MLBStatsAPIError, MLBStatsClient
|
|
16
|
+
from .modules.teams import get_teams
|
|
17
|
+
from .modules.roster import get_roster
|
|
18
|
+
from .modules.players import get_player_info, get_player_stats, get_player_career_splits
|
|
19
|
+
from .modules.games import get_schedule, get_boxscore, get_game_by_pk
|
|
20
|
+
|
|
21
|
+
__all__ = [
|
|
22
|
+
"MLBStatsClient",
|
|
23
|
+
"MLBStatsAPIError",
|
|
24
|
+
"get_teams",
|
|
25
|
+
"get_roster",
|
|
26
|
+
"get_player_info",
|
|
27
|
+
"get_player_stats",
|
|
28
|
+
"get_player_career_splits",
|
|
29
|
+
"get_schedule",
|
|
30
|
+
"get_boxscore",
|
|
31
|
+
"get_game_by_pk",
|
|
32
|
+
]
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
"""
|
|
2
|
+
MLB Stats API Client
|
|
3
|
+
====================
|
|
4
|
+
A Python wrapper for the official MLB Stats API (https://statsapi.mlb.com).
|
|
5
|
+
|
|
6
|
+
This module provides a low-level HTTP client that handles request construction,
|
|
7
|
+
error handling, and response parsing for the MLB Stats API.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
import requests
|
|
11
|
+
from typing import Any, Dict, Optional
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class MLBStatsAPIError(Exception):
|
|
15
|
+
"""Raised when the MLB Stats API returns an error response."""
|
|
16
|
+
|
|
17
|
+
def __init__(self, status_code: int, message: str):
|
|
18
|
+
self.status_code = status_code
|
|
19
|
+
self.message = message
|
|
20
|
+
super().__init__(f"MLB Stats API error {status_code}: {message}")
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class MLBStatsClient:
|
|
24
|
+
"""
|
|
25
|
+
Low-level HTTP client for the MLB Stats API.
|
|
26
|
+
|
|
27
|
+
Handles base URL configuration, session management, and common
|
|
28
|
+
request/response logic. Higher-level endpoint wrappers build on
|
|
29
|
+
top of this class.
|
|
30
|
+
|
|
31
|
+
Args:
|
|
32
|
+
base_url: The root URL of the Stats API. Defaults to the
|
|
33
|
+
official production endpoint.
|
|
34
|
+
timeout: Request timeout in seconds. Defaults to 10.
|
|
35
|
+
|
|
36
|
+
Example::
|
|
37
|
+
|
|
38
|
+
client = MLBStatsClient()
|
|
39
|
+
data = client.get("/api/v1/teams", params={"season": "2024", "sportId": 1})
|
|
40
|
+
"""
|
|
41
|
+
|
|
42
|
+
DEFAULT_BASE_URL = "https://statsapi.mlb.com"
|
|
43
|
+
|
|
44
|
+
def __init__(
|
|
45
|
+
self,
|
|
46
|
+
base_url: str = DEFAULT_BASE_URL,
|
|
47
|
+
timeout: int = 10,
|
|
48
|
+
):
|
|
49
|
+
self.base_url = base_url.rstrip("/")
|
|
50
|
+
self.timeout = timeout
|
|
51
|
+
self._session = requests.Session()
|
|
52
|
+
self._session.headers.update({"Accept": "application/json"})
|
|
53
|
+
|
|
54
|
+
def get(self, path: str, params: Optional[Dict[str, Any]] = None) -> Dict[str, Any]:
|
|
55
|
+
"""
|
|
56
|
+
Perform a GET request against the Stats API.
|
|
57
|
+
|
|
58
|
+
Args:
|
|
59
|
+
path: API path, e.g. ``"/api/v1/teams"``.
|
|
60
|
+
params: Optional dictionary of query-string parameters.
|
|
61
|
+
|
|
62
|
+
Returns:
|
|
63
|
+
Parsed JSON response as a Python dictionary.
|
|
64
|
+
|
|
65
|
+
Raises:
|
|
66
|
+
MLBStatsAPIError: If the server returns a non-2xx status code.
|
|
67
|
+
requests.RequestException: On network-level failures.
|
|
68
|
+
"""
|
|
69
|
+
url = f"{self.base_url}{path}"
|
|
70
|
+
response = self._session.get(url, params=params, timeout=self.timeout)
|
|
71
|
+
|
|
72
|
+
if not response.ok:
|
|
73
|
+
raise MLBStatsAPIError(response.status_code, response.text)
|
|
74
|
+
|
|
75
|
+
return response.json()
|
|
76
|
+
|
|
77
|
+
def close(self):
|
|
78
|
+
"""Close the underlying HTTP session, freeing connection-pool resources."""
|
|
79
|
+
self._session.close()
|
|
80
|
+
|
|
81
|
+
# Support use as a context manager
|
|
82
|
+
def __enter__(self):
|
|
83
|
+
return self
|
|
84
|
+
|
|
85
|
+
def __exit__(self, *_):
|
|
86
|
+
self.close()
|
|
File without changes
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Games
|
|
3
|
+
=====
|
|
4
|
+
Functions for retrieving MLB game schedule and score data from the Stats API.
|
|
5
|
+
|
|
6
|
+
The primary entry point is :func:`get_schedule`, which returns games for a
|
|
7
|
+
given date. By default it fetches regular-season MLB games only.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from typing import Any, Dict, List, Optional
|
|
11
|
+
|
|
12
|
+
from ..client import MLBStatsClient
|
|
13
|
+
|
|
14
|
+
_SCHEDULE_PATH = "/api/v1/schedule"
|
|
15
|
+
_BOXSCORE_PATH = "/api/v1/game/{game_pk}/boxscore"
|
|
16
|
+
|
|
17
|
+
MLB_SPORT_ID = 1
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def get_schedule(
|
|
21
|
+
date: str,
|
|
22
|
+
sport_id: int = MLB_SPORT_ID,
|
|
23
|
+
game_type: str = "R",
|
|
24
|
+
client: Optional[MLBStatsClient] = None,
|
|
25
|
+
) -> List[Dict[str, Any]]:
|
|
26
|
+
"""
|
|
27
|
+
Return all games scheduled for the given date.
|
|
28
|
+
|
|
29
|
+
Args:
|
|
30
|
+
date:
|
|
31
|
+
The date to query in ``YYYY-MM-DD`` format, e.g. ``"2024-04-01"``.
|
|
32
|
+
sport_id:
|
|
33
|
+
Top-level sport identifier. Use ``1`` (default) for MLB.
|
|
34
|
+
game_type:
|
|
35
|
+
Game type filter. ``"R"`` (default) returns regular-season games.
|
|
36
|
+
Pass ``"S"`` for spring training, ``"P"`` for playoffs, or ``"A"``
|
|
37
|
+
for the All-Star game.
|
|
38
|
+
client:
|
|
39
|
+
Optional pre-configured :class:`~baseball_api_wrapper.client.MLBStatsClient`.
|
|
40
|
+
If omitted, a default client is created for this single call.
|
|
41
|
+
|
|
42
|
+
Returns:
|
|
43
|
+
A list of game dictionaries as returned by the MLB Stats API
|
|
44
|
+
``/api/v1/schedule`` endpoint. Returns an empty list when no games
|
|
45
|
+
are scheduled for the requested date.
|
|
46
|
+
|
|
47
|
+
Raises:
|
|
48
|
+
baseball_api_wrapper.client.MLBStatsAPIError:
|
|
49
|
+
If the API returns a non-2xx HTTP status code.
|
|
50
|
+
requests.RequestException:
|
|
51
|
+
On network-level failures.
|
|
52
|
+
"""
|
|
53
|
+
params: Dict[str, Any] = {
|
|
54
|
+
"sportId": sport_id,
|
|
55
|
+
"date": date,
|
|
56
|
+
"gameType": game_type,
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
_owns_client = client is None
|
|
60
|
+
if _owns_client:
|
|
61
|
+
client = MLBStatsClient()
|
|
62
|
+
|
|
63
|
+
try:
|
|
64
|
+
data = client.get(_SCHEDULE_PATH, params=params)
|
|
65
|
+
finally:
|
|
66
|
+
if _owns_client:
|
|
67
|
+
client.close()
|
|
68
|
+
|
|
69
|
+
dates = data.get("dates", [])
|
|
70
|
+
if not dates:
|
|
71
|
+
return []
|
|
72
|
+
return dates[0].get("games", [])
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def get_game_by_pk(
|
|
76
|
+
game_pk: int,
|
|
77
|
+
client: Optional[MLBStatsClient] = None,
|
|
78
|
+
) -> Dict[str, Any]:
|
|
79
|
+
"""
|
|
80
|
+
Return the schedule entry for a single game by its ``gamePk``.
|
|
81
|
+
|
|
82
|
+
Useful for fetching lightweight metadata (status, date, teams) without
|
|
83
|
+
the full boxscore payload.
|
|
84
|
+
|
|
85
|
+
Args:
|
|
86
|
+
game_pk: The unique game identifier.
|
|
87
|
+
client: Optional pre-configured :class:`~baseball_api_wrapper.client.MLBStatsClient`.
|
|
88
|
+
|
|
89
|
+
Returns:
|
|
90
|
+
The game dictionary for the requested ``gamePk``, or an empty dict
|
|
91
|
+
if the game is not found.
|
|
92
|
+
"""
|
|
93
|
+
params: Dict[str, Any] = {"gamePks": game_pk, "sportId": MLB_SPORT_ID}
|
|
94
|
+
|
|
95
|
+
_owns_client = client is None
|
|
96
|
+
if _owns_client:
|
|
97
|
+
client = MLBStatsClient()
|
|
98
|
+
|
|
99
|
+
try:
|
|
100
|
+
data = client.get(_SCHEDULE_PATH, params=params)
|
|
101
|
+
finally:
|
|
102
|
+
if _owns_client:
|
|
103
|
+
client.close()
|
|
104
|
+
|
|
105
|
+
dates = data.get("dates", [])
|
|
106
|
+
if not dates:
|
|
107
|
+
return {}
|
|
108
|
+
games = dates[0].get("games", [])
|
|
109
|
+
return games[0] if games else {}
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
def get_boxscore(
|
|
113
|
+
game_pk: int,
|
|
114
|
+
client: Optional[MLBStatsClient] = None,
|
|
115
|
+
) -> Dict[str, Any]:
|
|
116
|
+
"""
|
|
117
|
+
Return the box score for a single game.
|
|
118
|
+
|
|
119
|
+
Args:
|
|
120
|
+
game_pk:
|
|
121
|
+
The unique game identifier (``gamePk``) returned by
|
|
122
|
+
:func:`get_schedule`.
|
|
123
|
+
client:
|
|
124
|
+
Optional pre-configured :class:`~baseball_api_wrapper.client.MLBStatsClient`.
|
|
125
|
+
If omitted, a default client is created for this single call.
|
|
126
|
+
|
|
127
|
+
Returns:
|
|
128
|
+
The raw box score dictionary as returned by the MLB Stats API
|
|
129
|
+
``/api/v1/game/{gamePk}/boxscore`` endpoint.
|
|
130
|
+
|
|
131
|
+
Raises:
|
|
132
|
+
baseball_api_wrapper.client.MLBStatsAPIError:
|
|
133
|
+
If the API returns a non-2xx HTTP status code.
|
|
134
|
+
requests.RequestException:
|
|
135
|
+
On network-level failures.
|
|
136
|
+
"""
|
|
137
|
+
path = _BOXSCORE_PATH.format(game_pk=game_pk)
|
|
138
|
+
|
|
139
|
+
_owns_client = client is None
|
|
140
|
+
if _owns_client:
|
|
141
|
+
client = MLBStatsClient()
|
|
142
|
+
|
|
143
|
+
try:
|
|
144
|
+
return client.get(path)
|
|
145
|
+
finally:
|
|
146
|
+
if _owns_client:
|
|
147
|
+
client.close()
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Players
|
|
3
|
+
=======
|
|
4
|
+
Functions for retrieving player information and statistics from the MLB Stats API.
|
|
5
|
+
|
|
6
|
+
The two primary entry points are:
|
|
7
|
+
|
|
8
|
+
* :func:`get_player_info` – Basic biographical data for a player.
|
|
9
|
+
* :func:`get_player_stats` – Season statistics for a player, split by group
|
|
10
|
+
(``"hitting"`` or ``"pitching"``).
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
from typing import Any, Dict, List, Optional
|
|
14
|
+
|
|
15
|
+
from ..client import MLBStatsClient
|
|
16
|
+
|
|
17
|
+
_PLAYER_INFO_PATH = "/api/v1/people/{player_id}"
|
|
18
|
+
_PLAYER_STATS_PATH = "/api/v1/people/{player_id}/stats"
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def get_player_career_splits(
|
|
22
|
+
player_id: int,
|
|
23
|
+
group: str = "hitting",
|
|
24
|
+
client: Optional[MLBStatsClient] = None,
|
|
25
|
+
) -> List[Dict[str, Any]]:
|
|
26
|
+
"""
|
|
27
|
+
Return year-by-year career splits for a player.
|
|
28
|
+
|
|
29
|
+
Each element in the returned list is a split dict with at minimum:
|
|
30
|
+
* ``season`` – The season year as a string, e.g. ``"2024"``.
|
|
31
|
+
* ``stat`` – Dict of raw stat fields for that season.
|
|
32
|
+
|
|
33
|
+
Args:
|
|
34
|
+
player_id: The player's unique MLB identifier.
|
|
35
|
+
group: ``"hitting"`` or ``"pitching"``. Defaults to ``"hitting"``.
|
|
36
|
+
client: Optional pre-configured MLBStatsClient.
|
|
37
|
+
|
|
38
|
+
Returns:
|
|
39
|
+
A list of split dicts, one per season, or an empty list if none found.
|
|
40
|
+
"""
|
|
41
|
+
path = _PLAYER_STATS_PATH.format(player_id=player_id)
|
|
42
|
+
params: Dict[str, Any] = {"stats": "yearByYear", "group": group, "hydrate": "team"}
|
|
43
|
+
|
|
44
|
+
_owns_client = client is None
|
|
45
|
+
if _owns_client:
|
|
46
|
+
client = MLBStatsClient()
|
|
47
|
+
|
|
48
|
+
try:
|
|
49
|
+
data = client.get(path, params=params)
|
|
50
|
+
finally:
|
|
51
|
+
if _owns_client:
|
|
52
|
+
client.close()
|
|
53
|
+
|
|
54
|
+
for stat_block in data.get("stats", []):
|
|
55
|
+
splits = stat_block.get("splits", [])
|
|
56
|
+
if splits:
|
|
57
|
+
return splits
|
|
58
|
+
|
|
59
|
+
return []
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def get_player_info(
|
|
63
|
+
player_id: int,
|
|
64
|
+
client: Optional[MLBStatsClient] = None,
|
|
65
|
+
) -> Dict[str, Any]:
|
|
66
|
+
"""
|
|
67
|
+
Return biographical information for a single player.
|
|
68
|
+
|
|
69
|
+
The returned dict contains at minimum:
|
|
70
|
+
|
|
71
|
+
* ``id`` – Player's unique MLB identifier.
|
|
72
|
+
* ``fullName`` – Full display name.
|
|
73
|
+
* ``primaryPosition`` – Nested dict with ``code``, ``name``, ``type``,
|
|
74
|
+
``abbreviation``.
|
|
75
|
+
* ``active`` – Boolean indicating whether the player is active.
|
|
76
|
+
|
|
77
|
+
Args:
|
|
78
|
+
player_id:
|
|
79
|
+
The player's unique MLB identifier, e.g. ``660271`` for Juan Soto.
|
|
80
|
+
client:
|
|
81
|
+
Optional pre-configured :class:`~baseball_api_wrapper.client.MLBStatsClient`.
|
|
82
|
+
If omitted, a default client is created for the single call.
|
|
83
|
+
|
|
84
|
+
Returns:
|
|
85
|
+
A dict of player attributes as returned by the MLB Stats API.
|
|
86
|
+
|
|
87
|
+
Raises:
|
|
88
|
+
mlb_statsapi.client.MLBStatsAPIError:
|
|
89
|
+
If the API returns a non-2xx HTTP status code.
|
|
90
|
+
requests.RequestException:
|
|
91
|
+
On network-level failures.
|
|
92
|
+
KeyError:
|
|
93
|
+
If the response contains no ``people`` entry for the given ID.
|
|
94
|
+
"""
|
|
95
|
+
path = _PLAYER_INFO_PATH.format(player_id=player_id)
|
|
96
|
+
|
|
97
|
+
_owns_client = client is None
|
|
98
|
+
if _owns_client:
|
|
99
|
+
client = MLBStatsClient()
|
|
100
|
+
|
|
101
|
+
try:
|
|
102
|
+
data = client.get(path)
|
|
103
|
+
finally:
|
|
104
|
+
if _owns_client:
|
|
105
|
+
client.close()
|
|
106
|
+
|
|
107
|
+
people: List[Dict[str, Any]] = data.get("people", [])
|
|
108
|
+
if not people:
|
|
109
|
+
raise KeyError(f"No player found with id {player_id}")
|
|
110
|
+
|
|
111
|
+
return people[0]
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
def get_player_stats(
|
|
115
|
+
player_id: int,
|
|
116
|
+
season: int | str,
|
|
117
|
+
group: str = "hitting",
|
|
118
|
+
client: Optional[MLBStatsClient] = None,
|
|
119
|
+
) -> Optional[Dict[str, Any]]:
|
|
120
|
+
"""
|
|
121
|
+
Return season statistics for a player for a specific stat group.
|
|
122
|
+
|
|
123
|
+
Args:
|
|
124
|
+
player_id:
|
|
125
|
+
The player's unique MLB identifier.
|
|
126
|
+
season:
|
|
127
|
+
The MLB season year, e.g. ``2024`` or ``"2024"``.
|
|
128
|
+
group:
|
|
129
|
+
The stat group to retrieve: ``"hitting"`` or ``"pitching"``.
|
|
130
|
+
Defaults to ``"hitting"``.
|
|
131
|
+
client:
|
|
132
|
+
Optional pre-configured :class:`~baseball_api_wrapper.client.MLBStatsClient`.
|
|
133
|
+
If omitted, a default client is created for the single call.
|
|
134
|
+
|
|
135
|
+
Returns:
|
|
136
|
+
A dict of raw stat fields as returned by the MLB Stats API (the
|
|
137
|
+
``stat`` object from the first split), or ``None`` if no stats are
|
|
138
|
+
available for this player/season/group combination.
|
|
139
|
+
|
|
140
|
+
Raises:
|
|
141
|
+
mlb_statsapi.client.MLBStatsAPIError:
|
|
142
|
+
If the API returns a non-2xx HTTP status code.
|
|
143
|
+
requests.RequestException:
|
|
144
|
+
On network-level failures.
|
|
145
|
+
|
|
146
|
+
Example::
|
|
147
|
+
|
|
148
|
+
from baseball_api_wrapper.modules.players import get_player_stats
|
|
149
|
+
|
|
150
|
+
# Juan Soto's 2024 hitting stats
|
|
151
|
+
stats = get_player_stats(660271, 2024, group="hitting")
|
|
152
|
+
if stats:
|
|
153
|
+
print(stats["avg"], stats["homeRuns"], stats["rbi"])
|
|
154
|
+
"""
|
|
155
|
+
path = _PLAYER_STATS_PATH.format(player_id=player_id)
|
|
156
|
+
|
|
157
|
+
params: Dict[str, Any] = {
|
|
158
|
+
"stats": "season",
|
|
159
|
+
"season": str(season),
|
|
160
|
+
"group": group,
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
_owns_client = client is None
|
|
164
|
+
if _owns_client:
|
|
165
|
+
client = MLBStatsClient()
|
|
166
|
+
|
|
167
|
+
try:
|
|
168
|
+
data = client.get(path, params=params)
|
|
169
|
+
finally:
|
|
170
|
+
if _owns_client:
|
|
171
|
+
client.close()
|
|
172
|
+
|
|
173
|
+
for stat_block in data.get("stats", []):
|
|
174
|
+
splits = stat_block.get("splits", [])
|
|
175
|
+
if splits:
|
|
176
|
+
return splits[0].get("stat")
|
|
177
|
+
|
|
178
|
+
return None
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Roster
|
|
3
|
+
======
|
|
4
|
+
Functions for retrieving team roster data from the MLB Stats API.
|
|
5
|
+
|
|
6
|
+
The primary entry point is :func:`get_roster`, which returns the list of
|
|
7
|
+
players (or coaches) on a team's roster for a given season.
|
|
8
|
+
|
|
9
|
+
Roster Types
|
|
10
|
+
------------
|
|
11
|
+
The API supports several roster types, all exposed via the :class:`RosterType`
|
|
12
|
+
enum. The most commonly used types are:
|
|
13
|
+
|
|
14
|
+
* ``ACTIVE`` – The 26-man active roster (in-season).
|
|
15
|
+
* ``FORTY_MAN`` – The full 40-man roster.
|
|
16
|
+
* ``FULL_SEASON`` – Everyone who appeared on the roster at any point
|
|
17
|
+
during the season.
|
|
18
|
+
* ``FULL_ROSTER`` – Alias similar to FULL_SEASON.
|
|
19
|
+
* ``NON_ROSTER_INVITEES`` – Spring training non-roster invitees.
|
|
20
|
+
* ``DEPTH_CHART`` – Organizational depth chart.
|
|
21
|
+
* ``GAMEDAY`` – Roster for a specific game day.
|
|
22
|
+
* ``ALL_TIME`` – All-time historical roster.
|
|
23
|
+
* ``COACH`` – Coaching staff.
|
|
24
|
+
"""
|
|
25
|
+
|
|
26
|
+
from enum import Enum
|
|
27
|
+
from typing import Any, Dict, List, Optional
|
|
28
|
+
|
|
29
|
+
from ..client import MLBStatsClient
|
|
30
|
+
|
|
31
|
+
# API path template for the roster endpoint. teamId is a required path param.
|
|
32
|
+
_ROSTER_PATH = "/api/v1/teams/{team_id}/roster"
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
class RosterType(str, Enum):
|
|
36
|
+
"""
|
|
37
|
+
Valid roster type identifiers accepted by the MLB Stats API.
|
|
38
|
+
|
|
39
|
+
Inherits from ``str`` so values can be passed directly wherever a
|
|
40
|
+
string is expected (e.g. as a query parameter).
|
|
41
|
+
"""
|
|
42
|
+
|
|
43
|
+
ACTIVE = "active"
|
|
44
|
+
FORTY_MAN = "40Man"
|
|
45
|
+
FULL_SEASON = "fullSeason"
|
|
46
|
+
FULL_ROSTER = "fullRoster"
|
|
47
|
+
NON_ROSTER_INVITEES = "nonRosterInvitees"
|
|
48
|
+
DEPTH_CHART = "depthChart"
|
|
49
|
+
GAMEDAY = "gameday"
|
|
50
|
+
ALL_TIME = "allTime"
|
|
51
|
+
COACH = "coach"
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def get_roster(
|
|
55
|
+
team_id: int,
|
|
56
|
+
season: int | str,
|
|
57
|
+
roster_type: RosterType | str = RosterType.ACTIVE,
|
|
58
|
+
date: Optional[str] = None,
|
|
59
|
+
client: Optional[MLBStatsClient] = None,
|
|
60
|
+
) -> List[Dict[str, Any]]:
|
|
61
|
+
"""
|
|
62
|
+
Return the roster for a team in a given MLB season.
|
|
63
|
+
|
|
64
|
+
Each entry in the returned list represents a single player (or coach,
|
|
65
|
+
depending on *roster_type*) and contains at minimum:
|
|
66
|
+
|
|
67
|
+
* ``person`` – dict with ``id``, ``fullName``, ``link``
|
|
68
|
+
* ``jerseyNumber`` – string jersey number
|
|
69
|
+
* ``position`` – dict with ``code``, ``name``, ``type``,
|
|
70
|
+
``abbreviation``
|
|
71
|
+
* ``status`` – dict describing roster transaction status
|
|
72
|
+
* ``parentTeamId`` – ID of the parent MLB club
|
|
73
|
+
|
|
74
|
+
Args:
|
|
75
|
+
team_id:
|
|
76
|
+
Unique team identifier, e.g. ``147`` for the New York Yankees.
|
|
77
|
+
Team IDs can be retrieved via :func:`~mlb_statsapi.teams.get_teams`.
|
|
78
|
+
season:
|
|
79
|
+
The MLB season year, e.g. ``2024`` or ``"2024"``.
|
|
80
|
+
roster_type:
|
|
81
|
+
The type of roster to retrieve. Accepts a :class:`RosterType`
|
|
82
|
+
member or the equivalent raw string value. Defaults to
|
|
83
|
+
:attr:`RosterType.ACTIVE` (the 26-man active roster).
|
|
84
|
+
date:
|
|
85
|
+
Optional date string in ``"YYYY-MM-DD"`` format. When provided,
|
|
86
|
+
the roster is returned as it stood on that date. Useful with
|
|
87
|
+
``roster_type=RosterType.GAMEDAY``.
|
|
88
|
+
client:
|
|
89
|
+
Optional pre-configured :class:`~mlb_statsapi.client.MLBStatsClient`
|
|
90
|
+
instance. If omitted, a default client pointing at the official
|
|
91
|
+
production endpoint is created and used for the single call.
|
|
92
|
+
|
|
93
|
+
Returns:
|
|
94
|
+
A list of roster-entry dictionaries as returned by the MLB Stats API.
|
|
95
|
+
Returns an empty list if the API response contains no roster entries.
|
|
96
|
+
|
|
97
|
+
Raises:
|
|
98
|
+
mlb_statsapi.client.MLBStatsAPIError:
|
|
99
|
+
If the API returns a non-2xx HTTP status code (e.g. 404 for an
|
|
100
|
+
unknown team ID).
|
|
101
|
+
requests.RequestException:
|
|
102
|
+
On network-level failures (timeouts, DNS errors, etc.).
|
|
103
|
+
ValueError:
|
|
104
|
+
If *date* is provided but does not match the ``YYYY-MM-DD`` format.
|
|
105
|
+
|
|
106
|
+
Example::
|
|
107
|
+
|
|
108
|
+
from mlb_statsapi.roster import get_roster, RosterType
|
|
109
|
+
|
|
110
|
+
# Active 26-man roster for the 2024 Yankees
|
|
111
|
+
roster = get_roster(147, 2024)
|
|
112
|
+
for entry in roster:
|
|
113
|
+
print(entry["jerseyNumber"], entry["person"]["fullName"])
|
|
114
|
+
|
|
115
|
+
# Full 40-man roster
|
|
116
|
+
roster_40 = get_roster(147, 2024, roster_type=RosterType.FORTY_MAN)
|
|
117
|
+
|
|
118
|
+
# Roster as of a specific date
|
|
119
|
+
roster_date = get_roster(147, 2024, date="2024-07-04")
|
|
120
|
+
"""
|
|
121
|
+
if date is not None:
|
|
122
|
+
_validate_date(date)
|
|
123
|
+
|
|
124
|
+
path = _ROSTER_PATH.format(team_id=team_id)
|
|
125
|
+
|
|
126
|
+
params: Dict[str, Any] = {
|
|
127
|
+
"season": str(season),
|
|
128
|
+
"rosterType": roster_type.value if isinstance(roster_type, RosterType) else roster_type,
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
if date is not None:
|
|
132
|
+
params["date"] = date
|
|
133
|
+
|
|
134
|
+
_owns_client = client is None
|
|
135
|
+
if _owns_client:
|
|
136
|
+
client = MLBStatsClient()
|
|
137
|
+
|
|
138
|
+
try:
|
|
139
|
+
data = client.get(path, params=params)
|
|
140
|
+
finally:
|
|
141
|
+
if _owns_client:
|
|
142
|
+
client.close()
|
|
143
|
+
|
|
144
|
+
return data.get("roster", [])
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
def _validate_date(date: str) -> None:
|
|
148
|
+
"""
|
|
149
|
+
Ensure *date* matches the ``YYYY-MM-DD`` format expected by the API.
|
|
150
|
+
|
|
151
|
+
Args:
|
|
152
|
+
date: Date string to validate.
|
|
153
|
+
|
|
154
|
+
Raises:
|
|
155
|
+
ValueError: If the string is not a valid ``YYYY-MM-DD`` date.
|
|
156
|
+
"""
|
|
157
|
+
import datetime
|
|
158
|
+
|
|
159
|
+
try:
|
|
160
|
+
datetime.date.fromisoformat(date)
|
|
161
|
+
except ValueError:
|
|
162
|
+
raise ValueError(
|
|
163
|
+
f"date must be in YYYY-MM-DD format, got {date!r}"
|
|
164
|
+
)
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Teams
|
|
3
|
+
=====
|
|
4
|
+
Functions for retrieving MLB team data from the Stats API.
|
|
5
|
+
|
|
6
|
+
The primary entry point is :func:`get_teams`, which returns a list of teams
|
|
7
|
+
for a given MLB season. Optional filters let callers narrow results by
|
|
8
|
+
league, division, or active status.
|
|
9
|
+
|
|
10
|
+
MLB Sport IDs
|
|
11
|
+
-------------
|
|
12
|
+
The Stats API serves data for multiple sports / levels. When fetching
|
|
13
|
+
official MLB teams you almost always want ``sport_id=1`` (the default).
|
|
14
|
+
|
|
15
|
+
Common sport IDs:
|
|
16
|
+
* 1 – MLB (majors)
|
|
17
|
+
* 11 – Triple-A
|
|
18
|
+
* 12 – Double-A
|
|
19
|
+
* 13 – High-A
|
|
20
|
+
* 14 – Single-A
|
|
21
|
+
|
|
22
|
+
Common league IDs:
|
|
23
|
+
* 103 – American League
|
|
24
|
+
* 104 – National League
|
|
25
|
+
"""
|
|
26
|
+
|
|
27
|
+
from typing import Any, Dict, List, Optional
|
|
28
|
+
|
|
29
|
+
from ..client import MLBStatsClient
|
|
30
|
+
|
|
31
|
+
# The Stats API path for the teams collection resource.
|
|
32
|
+
_TEAMS_PATH = "/api/v1/teams"
|
|
33
|
+
|
|
34
|
+
# Sport ID for MLB (major leagues).
|
|
35
|
+
MLB_SPORT_ID = 1
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def get_teams(
|
|
39
|
+
season: int | str,
|
|
40
|
+
sport_id: int = MLB_SPORT_ID,
|
|
41
|
+
league_ids: Optional[List[int]] = None,
|
|
42
|
+
division_id: Optional[int] = None,
|
|
43
|
+
active_status: Optional[str] = None,
|
|
44
|
+
client: Optional[MLBStatsClient] = None,
|
|
45
|
+
) -> List[Dict[str, Any]]:
|
|
46
|
+
"""
|
|
47
|
+
Return a list of MLB teams for the specified season.
|
|
48
|
+
|
|
49
|
+
Each team is represented as a dictionary containing at minimum:
|
|
50
|
+
``id``, ``name``, ``teamCode``, ``abbreviation``, ``teamName``,
|
|
51
|
+
``locationName``, ``league``, ``division``, and ``venue``.
|
|
52
|
+
|
|
53
|
+
Args:
|
|
54
|
+
season:
|
|
55
|
+
The MLB season year to query, e.g. ``2024`` or ``"2024"``.
|
|
56
|
+
sport_id:
|
|
57
|
+
Top-level sport identifier. Use ``1`` (default) for MLB
|
|
58
|
+
major-league teams. Pass a different value to retrieve teams
|
|
59
|
+
from the minors or other affiliated leagues.
|
|
60
|
+
league_ids:
|
|
61
|
+
Optional list of league IDs to filter results. For example,
|
|
62
|
+
``[103]`` returns only American League teams and ``[104]``
|
|
63
|
+
returns only National League teams.
|
|
64
|
+
division_id:
|
|
65
|
+
Optional single division ID to restrict results to one division
|
|
66
|
+
(e.g. ``200`` for AL West).
|
|
67
|
+
active_status:
|
|
68
|
+
Controls which teams are included based on their franchise
|
|
69
|
+
status. Accepted values:
|
|
70
|
+
|
|
71
|
+
* ``"Y"`` – active franchises only (default API behaviour)
|
|
72
|
+
* ``"N"`` – inactive / historical franchises only
|
|
73
|
+
* ``"P"`` – pending franchises
|
|
74
|
+
* ``"B"`` – all franchises regardless of status
|
|
75
|
+
|
|
76
|
+
client:
|
|
77
|
+
Optional pre-configured :class:`~mlb_statsapi.client.MLBStatsClient`
|
|
78
|
+
instance. If omitted, a default client pointing at the official
|
|
79
|
+
production endpoint is created and used for the single call.
|
|
80
|
+
|
|
81
|
+
Returns:
|
|
82
|
+
A list of team dictionaries as returned by the MLB Stats API.
|
|
83
|
+
Returns an empty list if the API response contains no teams.
|
|
84
|
+
|
|
85
|
+
Raises:
|
|
86
|
+
mlb_statsapi.client.MLBStatsAPIError:
|
|
87
|
+
If the API returns a non-2xx HTTP status code.
|
|
88
|
+
requests.RequestException:
|
|
89
|
+
On network-level failures (timeouts, DNS errors, etc.).
|
|
90
|
+
ValueError:
|
|
91
|
+
If *active_status* is not one of the accepted values.
|
|
92
|
+
|
|
93
|
+
Example::
|
|
94
|
+
|
|
95
|
+
from mlb_statsapi.teams import get_teams
|
|
96
|
+
|
|
97
|
+
# All 30 MLB teams for the 2024 season
|
|
98
|
+
teams = get_teams(2024)
|
|
99
|
+
for team in teams:
|
|
100
|
+
print(team["id"], team["name"])
|
|
101
|
+
|
|
102
|
+
# Only American League teams
|
|
103
|
+
al_teams = get_teams(2024, league_ids=[103])
|
|
104
|
+
|
|
105
|
+
# All historical franchises (active + inactive)
|
|
106
|
+
all_franchises = get_teams(2024, active_status="B")
|
|
107
|
+
"""
|
|
108
|
+
valid_statuses = {"Y", "N", "P", "B"}
|
|
109
|
+
if active_status is not None and active_status not in valid_statuses:
|
|
110
|
+
raise ValueError(
|
|
111
|
+
f"active_status must be one of {sorted(valid_statuses)}, "
|
|
112
|
+
f"got {active_status!r}"
|
|
113
|
+
)
|
|
114
|
+
|
|
115
|
+
params: Dict[str, Any] = {
|
|
116
|
+
"season": str(season),
|
|
117
|
+
"sportId": sport_id,
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
if league_ids is not None:
|
|
121
|
+
# The API accepts a comma-separated list for leagueIds.
|
|
122
|
+
params["leagueIds"] = ",".join(str(lid) for lid in league_ids)
|
|
123
|
+
|
|
124
|
+
if division_id is not None:
|
|
125
|
+
params["divisionId"] = division_id
|
|
126
|
+
|
|
127
|
+
if active_status is not None:
|
|
128
|
+
params["activeStatus"] = active_status
|
|
129
|
+
|
|
130
|
+
# Allow callers to inject a client (useful for testing / custom config).
|
|
131
|
+
# If none is provided, create a throw-away default client.
|
|
132
|
+
_owns_client = client is None
|
|
133
|
+
if _owns_client:
|
|
134
|
+
client = MLBStatsClient()
|
|
135
|
+
|
|
136
|
+
try:
|
|
137
|
+
data = client.get(_TEAMS_PATH, params=params)
|
|
138
|
+
finally:
|
|
139
|
+
if _owns_client:
|
|
140
|
+
client.close()
|
|
141
|
+
|
|
142
|
+
return data.get("teams", [])
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: baseball-api-wrapper
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: A Python wrapper for the official MLB Stats API (https://statsapi.mlb.com)
|
|
5
|
+
License-Expression: MIT
|
|
6
|
+
Requires-Python: >=3.9
|
|
7
|
+
Description-Content-Type: text/markdown
|
|
8
|
+
License-File: LICENSE
|
|
9
|
+
Requires-Dist: requests>=2.28
|
|
10
|
+
Provides-Extra: dev
|
|
11
|
+
Requires-Dist: pytest>=7.0; extra == "dev"
|
|
12
|
+
Requires-Dist: pytest-cov>=4.0; extra == "dev"
|
|
13
|
+
Requires-Dist: responses>=0.23; extra == "dev"
|
|
14
|
+
Dynamic: license-file
|
|
15
|
+
|
|
16
|
+
# baseball-api-wrapper
|
|
17
|
+
|
|
18
|
+
A Python wrapper for the official [MLB Stats API](https://statsapi.mlb.com).
|
|
19
|
+
|
|
20
|
+
## Installation
|
|
21
|
+
|
|
22
|
+
Clone the repo and install in editable mode so changes to the source are reflected immediately:
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
git clone <your-repo-url>
|
|
26
|
+
cd baseball-api-wrapper
|
|
27
|
+
pip install -e ".[dev]" # includes pytest and test dependencies
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
For use in another project without dev tools:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
pip install -e /path/to/baseball-api-wrapper
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Quick Start
|
|
37
|
+
|
|
38
|
+
```python
|
|
39
|
+
from baseball_api_wrapper import get_teams, get_roster
|
|
40
|
+
|
|
41
|
+
# List all MLB teams for the 2024 season
|
|
42
|
+
teams = get_teams(2024)
|
|
43
|
+
for team in teams:
|
|
44
|
+
print(team["id"], team["name"])
|
|
45
|
+
|
|
46
|
+
# Get the active roster for the New York Yankees (teamId=147)
|
|
47
|
+
roster = get_roster(147, season=2024)
|
|
48
|
+
for player in roster:
|
|
49
|
+
print(player["person"]["fullName"], player["position"]["name"])
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Using the Low-Level Client
|
|
53
|
+
|
|
54
|
+
For endpoints not yet covered by a module, use `MLBStatsClient` directly:
|
|
55
|
+
|
|
56
|
+
```python
|
|
57
|
+
from baseball_api_wrapper import MLBStatsClient
|
|
58
|
+
|
|
59
|
+
with MLBStatsClient() as client:
|
|
60
|
+
data = client.get("/api/v1/standings", params={"leagueId": 103, "season": 2024})
|
|
61
|
+
print(data)
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## Project Structure
|
|
65
|
+
|
|
66
|
+
```
|
|
67
|
+
baseball_api_wrapper/ # Installable package
|
|
68
|
+
__init__.py # Public API surface
|
|
69
|
+
client.py # Low-level HTTP client (MLBStatsClient, MLBStatsAPIError)
|
|
70
|
+
modules/
|
|
71
|
+
teams.py # get_teams()
|
|
72
|
+
roster.py # get_roster()
|
|
73
|
+
tests/ # pytest test suite
|
|
74
|
+
test_teams.py
|
|
75
|
+
test_roster.py
|
|
76
|
+
pyproject.toml # Build & dependency config
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
## Running Tests
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
pytest # Run all tests
|
|
83
|
+
pytest --cov=baseball_api_wrapper # Run with coverage report
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## Error Handling
|
|
87
|
+
|
|
88
|
+
Network or API errors raise `MLBStatsAPIError`:
|
|
89
|
+
|
|
90
|
+
```python
|
|
91
|
+
from baseball_api_wrapper import MLBStatsClient, MLBStatsAPIError
|
|
92
|
+
|
|
93
|
+
try:
|
|
94
|
+
with MLBStatsClient() as client:
|
|
95
|
+
data = client.get("/api/v1/teams/99999") # Non-existent team
|
|
96
|
+
except MLBStatsAPIError as e:
|
|
97
|
+
print(f"API error {e.status_code}: {e.message}")
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
## License
|
|
101
|
+
|
|
102
|
+
MIT — see [LICENSE](LICENSE) for details.
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
baseball_api_wrapper/__init__.py,sha256=CXwPig_Ts_GRRsGpxOr6gr_vqP7HBqhKIT-9oGqr9pE,807
|
|
2
|
+
baseball_api_wrapper/client.py,sha256=fp0_fV8O0Lv-SL6eBoopINeLddn133Yiv7JQeDdh7jU,2605
|
|
3
|
+
baseball_api_wrapper/modules/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
4
|
+
baseball_api_wrapper/modules/games.py,sha256=4QGc77PJsuuPFEQREgF54VqeVdNCA62s467WNSP3QBU,4167
|
|
5
|
+
baseball_api_wrapper/modules/players.py,sha256=8zg1xMO81u21brAb1eBrBGL1encRNQBq62D2tW7kX-c,5359
|
|
6
|
+
baseball_api_wrapper/modules/roster.py,sha256=yHsZJ5_aikR4_b2kfl3SAh4MyntRgB75qsseZGoINIw,5422
|
|
7
|
+
baseball_api_wrapper/modules/teams.py,sha256=HyuNS-IVTVddZY3bfOFA5PDsvwylHlXxZiffki789M0,4649
|
|
8
|
+
baseball_api_wrapper-0.1.0.dist-info/licenses/LICENSE,sha256=ESYyLizI0WWtxMeS7rGVcX3ivMezm-HOd5WdeOh-9oU,1056
|
|
9
|
+
baseball_api_wrapper-0.1.0.dist-info/METADATA,sha256=9US0YflCIZVMWreIhtOdy0WQ86agK894tYQj6ltG3Dc,2591
|
|
10
|
+
baseball_api_wrapper-0.1.0.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
|
|
11
|
+
baseball_api_wrapper-0.1.0.dist-info/top_level.txt,sha256=Xywgv0rkNorrhzYPkSVaq1QJ7dvwrmSK3srpp1F5Xr8,21
|
|
12
|
+
baseball_api_wrapper-0.1.0.dist-info/RECORD,,
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
baseball_api_wrapper
|