baseball-api-wrapper 0.1.0__tar.gz
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-0.1.0/LICENSE +21 -0
- baseball_api_wrapper-0.1.0/PKG-INFO +102 -0
- baseball_api_wrapper-0.1.0/README.md +87 -0
- baseball_api_wrapper-0.1.0/baseball_api_wrapper/__init__.py +32 -0
- baseball_api_wrapper-0.1.0/baseball_api_wrapper/client.py +86 -0
- baseball_api_wrapper-0.1.0/baseball_api_wrapper/modules/__init__.py +0 -0
- baseball_api_wrapper-0.1.0/baseball_api_wrapper/modules/games.py +147 -0
- baseball_api_wrapper-0.1.0/baseball_api_wrapper/modules/players.py +178 -0
- baseball_api_wrapper-0.1.0/baseball_api_wrapper/modules/roster.py +164 -0
- baseball_api_wrapper-0.1.0/baseball_api_wrapper/modules/teams.py +142 -0
- baseball_api_wrapper-0.1.0/baseball_api_wrapper.egg-info/PKG-INFO +102 -0
- baseball_api_wrapper-0.1.0/baseball_api_wrapper.egg-info/SOURCES.txt +19 -0
- baseball_api_wrapper-0.1.0/baseball_api_wrapper.egg-info/dependency_links.txt +1 -0
- baseball_api_wrapper-0.1.0/baseball_api_wrapper.egg-info/requires.txt +6 -0
- baseball_api_wrapper-0.1.0/baseball_api_wrapper.egg-info/top_level.txt +1 -0
- baseball_api_wrapper-0.1.0/pyproject.toml +36 -0
- baseball_api_wrapper-0.1.0/setup.cfg +4 -0
- baseball_api_wrapper-0.1.0/tests/test_games.py +306 -0
- baseball_api_wrapper-0.1.0/tests/test_players.py +354 -0
- baseball_api_wrapper-0.1.0/tests/test_roster.py +238 -0
- baseball_api_wrapper-0.1.0/tests/test_teams.py +234 -0
|
@@ -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,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,87 @@
|
|
|
1
|
+
# baseball-api-wrapper
|
|
2
|
+
|
|
3
|
+
A Python wrapper for the official [MLB Stats API](https://statsapi.mlb.com).
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
Clone the repo and install in editable mode so changes to the source are reflected immediately:
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
git clone <your-repo-url>
|
|
11
|
+
cd baseball-api-wrapper
|
|
12
|
+
pip install -e ".[dev]" # includes pytest and test dependencies
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
For use in another project without dev tools:
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
pip install -e /path/to/baseball-api-wrapper
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Quick Start
|
|
22
|
+
|
|
23
|
+
```python
|
|
24
|
+
from baseball_api_wrapper import get_teams, get_roster
|
|
25
|
+
|
|
26
|
+
# List all MLB teams for the 2024 season
|
|
27
|
+
teams = get_teams(2024)
|
|
28
|
+
for team in teams:
|
|
29
|
+
print(team["id"], team["name"])
|
|
30
|
+
|
|
31
|
+
# Get the active roster for the New York Yankees (teamId=147)
|
|
32
|
+
roster = get_roster(147, season=2024)
|
|
33
|
+
for player in roster:
|
|
34
|
+
print(player["person"]["fullName"], player["position"]["name"])
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Using the Low-Level Client
|
|
38
|
+
|
|
39
|
+
For endpoints not yet covered by a module, use `MLBStatsClient` directly:
|
|
40
|
+
|
|
41
|
+
```python
|
|
42
|
+
from baseball_api_wrapper import MLBStatsClient
|
|
43
|
+
|
|
44
|
+
with MLBStatsClient() as client:
|
|
45
|
+
data = client.get("/api/v1/standings", params={"leagueId": 103, "season": 2024})
|
|
46
|
+
print(data)
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Project Structure
|
|
50
|
+
|
|
51
|
+
```
|
|
52
|
+
baseball_api_wrapper/ # Installable package
|
|
53
|
+
__init__.py # Public API surface
|
|
54
|
+
client.py # Low-level HTTP client (MLBStatsClient, MLBStatsAPIError)
|
|
55
|
+
modules/
|
|
56
|
+
teams.py # get_teams()
|
|
57
|
+
roster.py # get_roster()
|
|
58
|
+
tests/ # pytest test suite
|
|
59
|
+
test_teams.py
|
|
60
|
+
test_roster.py
|
|
61
|
+
pyproject.toml # Build & dependency config
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## Running Tests
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
pytest # Run all tests
|
|
68
|
+
pytest --cov=baseball_api_wrapper # Run with coverage report
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## Error Handling
|
|
72
|
+
|
|
73
|
+
Network or API errors raise `MLBStatsAPIError`:
|
|
74
|
+
|
|
75
|
+
```python
|
|
76
|
+
from baseball_api_wrapper import MLBStatsClient, MLBStatsAPIError
|
|
77
|
+
|
|
78
|
+
try:
|
|
79
|
+
with MLBStatsClient() as client:
|
|
80
|
+
data = client.get("/api/v1/teams/99999") # Non-existent team
|
|
81
|
+
except MLBStatsAPIError as e:
|
|
82
|
+
print(f"API error {e.status_code}: {e.message}")
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## License
|
|
86
|
+
|
|
87
|
+
MIT — see [LICENSE](LICENSE) for details.
|
|
@@ -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
|