Skip to content

Commit 4bf811b

Browse files
authored
Merge pull request #238 from zero-sum-seattle/codex/remove-mlb-data-adapter-function
refactor: remove key transformation and use native camelCase API responses
2 parents 7004de7 + df222c2 commit 4bf811b

109 files changed

Lines changed: 906 additions & 23315 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/build-and-test-mlbstatsapi-prd.yml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,6 @@ jobs:
2525
virtualenvs-in-project: true
2626
- name: Install dependencies
2727
run: poetry install --no-interaction
28-
- name: Test with mocks with pytest
29-
run: poetry run pytest tests/mock_tests/
3028
- name: Test external tests with pytest
3129
run: poetry run pytest tests/external_tests/
3230
- name: Build package

.github/workflows/build-and-test-mlbstatsapi-test.yml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,6 @@ jobs:
2525
virtualenvs-in-project: true
2626
- name: Install dependencies
2727
run: poetry install --no-interaction
28-
- name: Test with mocks with pytest
29-
run: poetry run pytest tests/mock_tests/
3028
- name: Test external tests with pytest
3129
run: poetry run pytest tests/external_tests/
3230
- name: Build package

.github/workflows/build-and-test.yml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,6 @@ jobs:
2626
virtualenvs-in-project: true
2727
- name: Install dependencies
2828
run: poetry install --no-interaction
29-
- name: Test with mocks with pytest
30-
run: poetry run pytest tests/mock_tests/
3129
- name: Test external tests with pytest
3230
run: poetry run pytest tests/external_tests/
3331
- name: Build package

README.md

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ Ty France
5656
>>> groups = ['hitting']
5757
>>> params = {'season': 2022}
5858
>>> mlb.get_player_stats(664034, stats, groups, **params)
59-
{'hitting': {'season': Stat, 'seasonadvanced': Stat }}
59+
{'hitting': {'season': Stat, 'seasonAdvanced': Stat }}
6060

6161
>>> mlb.get_team_id("Seattle Mariners")
6262
[136]
@@ -185,9 +185,6 @@ Contributions are welcome! Whether it's bug fixes, new features, or documentatio
185185
# Run tests
186186
poetry run pytest
187187

188-
# Run mock tests only (no external API calls)
189-
poetry run pytest tests/mock_tests/
190-
191188
# Run external tests (requires internet)
192189
poetry run pytest tests/external_tests/
193190
```
@@ -277,7 +274,7 @@ Use team id and the stat types and groups to return season hitting stats
277274
```python
278275
>>> stats = mlb.get_team_stats(team_id, stats=stats, groups=groups, **params)
279276
>>> season_hitting = stats['hitting']['season']
280-
>>> advanced_hitting = stats['hitting']['seasonadvanced']
277+
>>> advanced_hitting = stats['hitting']['seasonAdvanced']
281278
```
282279

283280
Print stats as JSON
@@ -301,7 +298,7 @@ Print stats as JSON
301298
>>> params = {'season': 2022}
302299

303300
>>> stats = mlb.get_player_stats(player_id, stats=stats, groups=group, **params)
304-
>>> expected = stats['hitting']['expectedstatistics']
301+
>>> expected = stats['hitting']['expectedStatistics']
305302
>>> for split in expected.splits:
306303
... print(f"Expected AVG: {split.stat.avg}")
307304
... print(f"Expected SLG: {split.stat.slg}")
@@ -326,7 +323,7 @@ Set stat type, stat groups, and params
326323
Get stats
327324
```python
328325
>>> stats = mlb.get_player_stats(ty_france_id, stats=stats, groups=group, **params)
329-
>>> vs_player = stats['hitting']['vsplayer']
326+
>>> vs_player = stats['hitting']['vsPlayer']
330327
>>> for split in vs_player.splits:
331328
... print(f"Games: {split.stat.games_played}, Hits: {split.stat.hits}")
332329
Games: 2, Hits: 2
@@ -340,7 +337,7 @@ Games: 2, Hits: 2
340337
>>> params = {'season': 2022}
341338

342339
>>> hotcoldzones = mlb.get_player_stats(ty_france_id, stats=stats, groups=hitting_group, **params)
343-
>>> zones = hotcoldzones['stats']['hotcoldzones']
340+
>>> zones = hotcoldzones['stats']['hotColdZones']
344341

345342
>>> for split in zones.splits:
346343
... print(f"Stat: {split.stat.name}")

mlbstatsapi/mlb_api.py

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,7 @@ def get_persons(self, person_ids: Union[str, List[int]], **params) -> List[Perso
193193
return person_list
194194

195195
def get_people_id(self, fullname: str, sport_id: int = 1,
196-
search_key: str = 'fullname', **params) -> List[int]:
196+
search_key: str = 'fullName', **params) -> List[int]:
197197
"""
198198
Returns specific player information based on players fullname
199199
@@ -903,7 +903,7 @@ def get_game(self, game_id: int, **params) -> Union[Game, None]:
903903
if 400 <= mlb_data.status_code <= 499:
904904
return None
905905

906-
if 'gamepk' in mlb_data.data and mlb_data.data['gamepk'] == game_id:
906+
if 'gamePk' in mlb_data.data and mlb_data.data['gamePk'] == game_id:
907907
return Game(**mlb_data.data)
908908

909909
def get_game_play_by_play(self, game_id: int, **params) -> Union[Plays, None]:
@@ -948,7 +948,7 @@ def get_game_play_by_play(self, game_id: int, **params) -> Union[Plays, None]:
948948
if 400 <= mlb_data.status_code <= 499:
949949
return None
950950

951-
if 'allplays' in mlb_data.data and mlb_data.data['allplays']:
951+
if 'allPlays' in mlb_data.data and mlb_data.data['allPlays']:
952952
return Plays(**mlb_data.data)
953953

954954
def get_game_line_score(self, game_id: int, **params) -> Union[Linescore, None]:
@@ -1095,7 +1095,7 @@ def get_game_ids(self, date: str = None,
10951095
if 'dates' in mlb_data.data and mlb_data.data['dates']:
10961096
for date in mlb_data.data['dates']:
10971097
for game in date['games']:
1098-
game_ids.append(game.gamepk)
1098+
game_ids.append(game['gamePk'])
10991099

11001100
return game_ids
11011101

@@ -2027,7 +2027,7 @@ def get_homerun_derby(self, game_id, **params) -> Union[HomeRunDerby, None]:
20272027
Parameters
20282028
----------
20292029
game_id : int
2030-
Insert gamePk to return HomerunDerby data for a specific gamepk.
2030+
Insert gamePk to return HomerunDerby data for a specific gamePk.
20312031
20322032
Other Parameters
20332033
----------------
@@ -2088,7 +2088,7 @@ def get_team_stats(self, team_id: int, stats: list, groups: list, **params) -> d
20882088
>>> stats = ['season', 'seasonAdvanced']
20892089
>>> groups = ['pitching']
20902090
>>> mlb.get_team_stats(133, stats, groups)
2091-
{'pitching': {'season': [PitchingSeason], 'seasonadvanced': [PitchingSeasonAdvanced] }}
2091+
{'pitching': {'season': [PitchingSeason], 'seasonAdvanced': [PitchingSeasonAdvanced] }}
20922092
"""
20932093
params['stats'] = stats
20942094
params['group'] = groups
@@ -2134,8 +2134,8 @@ def get_players_stats_for_game(self, person_id: int, game_id: int, **params) ->
21342134
>>> player_id = 663728
21352135
>>> game_id = 715757
21362136
>>> stats = mlb.get_player_stats_for_game(person_id=person_id, game_id=game_id)
2137-
>>> print(stats['stats']['gamelog'])
2138-
>>> print(stats['hitting']['playlog'])
2137+
>>> print(stats['stats']['gameLog'])
2138+
>>> print(stats['hitting']['playLog'])
21392139
"""
21402140
mlb_data = self._mlb_adapter_v1.get(endpoint=f'people/{person_id}/stats/game/{game_id}')
21412141
if 400 <= mlb_data.status_code <= 499:
@@ -2166,7 +2166,7 @@ def get_player_stats(self, person_id: int, stats: list, groups: list, **params)
21662166
season : str
21672167
Insert year to return team stats for a particular season, season=2018
21682168
eventType : str
2169-
Notes for individual events for playLog, playlog can be filered by individual events.
2169+
Notes for individual events for playLog, playLog can be filered by individual events.
21702170
List of eventTypes can be found at https://statsapi.mlb.com/api/v1/eventTypes
21712171
21722172
Returns
@@ -2186,7 +2186,7 @@ def get_player_stats(self, person_id: int, stats: list, groups: list, **params)
21862186
>>> stats = ['season', 'seasonAdvanced']
21872187
>>> groups = ['hitting']
21882188
>>> mlb.get_player_stats(647351, stats, groups)
2189-
{'hitting': {'season': [HittingSeason], 'seasonadvanced': [HittingSeasonAdvanced] }}
2189+
{'hitting': {'season': [HittingSeason], 'seasonAdvanced': [HittingSeasonAdvanced] }}
21902190
"""
21912191
params['stats'] = stats
21922192
params['group'] = groups
@@ -2262,4 +2262,3 @@ def get_stats(self, stats: list, groups: list, **params: dict) -> dict:
22622262
return splits
22632263

22642264
# This is to test pypi, please delete later
2265-

mlbstatsapi/mlb_dataadapter.py

Lines changed: 1 addition & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from typing import Dict, List
1+
from typing import Dict
22
from .exceptions import TheMlbStatsApiException
33
import requests
44
import logging
@@ -46,39 +46,6 @@ def __init__(self, hostname: str = 'statsapi.mlb.com', ver: str = 'v1', logger:
4646
self._logger = logger or logging.getLogger(__name__)
4747
self._logger.setLevel(logging.DEBUG)
4848

49-
def _transform_keys_in_data(self, data) -> dict:
50-
"""
51-
Recursivly transform all the keys in a dictionary to lowercase
52-
53-
Parameters
54-
----------
55-
data : dict
56-
MlbResult data dictionary
57-
58-
Returns
59-
-------
60-
dict
61-
"""
62-
63-
if isinstance(data, Dict):
64-
lowered_dict = {}
65-
66-
for key, value in data.items():
67-
lowered_dict[key.lower()] = self._transform_keys_in_data(value)
68-
69-
return lowered_dict
70-
71-
elif isinstance(data, List):
72-
lowered_list = []
73-
74-
for item in data:
75-
lowered_list.append(self._transform_keys_in_data(item))
76-
77-
return lowered_list
78-
79-
else:
80-
return data
81-
8249
def get(self, endpoint: str, ep_params: Dict = None, data: Dict = None) -> MlbResult:
8350
"""
8451
return a MlbResult from endpoint
@@ -98,7 +65,6 @@ def get(self, endpoint: str, ep_params: Dict = None, data: Dict = None) -> MlbRe
9865
"""
9966

10067
full_url = self.url + endpoint
101-
print (full_url)
10268
logline_pre = f'url={full_url}'
10369
logline_post = " ,".join((logline_pre, 'success={}, status_code={}, message={}, url={}'))
10470

@@ -121,7 +87,6 @@ def get(self, endpoint: str, ep_params: Dict = None, data: Dict = None) -> MlbRe
12187
self._logger.debug(msg=logline_post.format('success',
12288
response.status_code, response.reason, response.url))
12389

124-
data = self._transform_keys_in_data(data)
12590
return MlbResult(response.status_code, message=response.reason, data=data)
12691

12792
elif response.status_code >= 400 and response.status_code <= 499:

mlbstatsapi/mlb_module.py

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -114,14 +114,14 @@ def create_split_data(stat_data: dict) -> dict:
114114
if 'splits' in stat and stat['splits']:
115115
split_data = return_splits(stat['splits'], stat_type, stat_group)
116116
stat_object = Stat(group=stat_group, type=stat_type,
117-
totalsplits=total_splits, splits=split_data)
117+
totalSplits=total_splits, splits=split_data)
118118
else:
119119
continue
120120

121121
if stat_group not in stats:
122122
stats[stat_group] = {}
123123

124-
stats[stat_group][stat_type.lower()] = stat_object
124+
stats[stat_group][stat_type] = stat_object
125125

126126
return stats
127127

@@ -137,26 +137,25 @@ def get_stat_attributes(stats) -> str:
137137
-------
138138
(stat_type, stat_group)
139139
"""
140-
if 'type' in stats and 'displayname' in stats['type']:
141-
stat_type = stats['type']['displayname']
140+
if 'type' in stats and 'displayName' in stats['type']:
141+
stat_type = stats['type']['displayName']
142142
else:
143143
stat_type = 'gameLog'
144144

145145
# default to stats if no group returned
146-
if 'group' in stats and 'displayname' in stats['group']:
147-
stat_group = stats['group']['displayname']
146+
if 'group' in stats and 'displayName' in stats['group']:
147+
stat_group = stats['group']['displayName']
148148
else:
149149
# if stat_type is None return None
150150
if stat_type:
151151
stat_group = 'stats'
152152
else:
153153
stat_group = None
154154

155-
if 'totalsplits' in stats:
156-
total_splits = stats['totalsplits']
155+
if 'totalSplits' in stats:
156+
total_splits = stats['totalSplits']
157157
else:
158158
total_splits = len(stats['splits'])
159159

160160
return (stat_type, stat_group, total_splits)
161161

162-

mlbstatsapi/models/attendances/attendance.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,5 @@ class Attendance(MLBBaseModel):
1515
aggregate_totals : AttendanceTotals
1616
Attendance aggregate total numbers for query.
1717
"""
18-
aggregate_totals: AttendanceTotals = Field(alias="aggregatetotals")
18+
aggregate_totals: AttendanceTotals = Field(alias="aggregateTotals")
1919
records: List[AttendanceRecords] = []

mlbstatsapi/models/attendances/attributes.py

Lines changed: 35 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,10 @@ class AttendanceHighLowGame(MLBBaseModel):
3131
day_night : str
3232
Time of day for game (day or night).
3333
"""
34-
game_pk: int = Field(alias="gamepk")
34+
game_pk: int = Field(alias="gamePk")
3535
link: str
3636
content: AttendanceHighLowGameContent
37-
day_night: str = Field(alias="daynight")
37+
day_night: str = Field(alias="dayNight")
3838

3939

4040
class AttendanceGameType(MLBBaseModel):
@@ -105,29 +105,29 @@ class AttendanceRecords(MLBBaseModel):
105105
team : Team
106106
Team.
107107
"""
108-
openings_total: int = Field(alias="openingstotal")
109-
openings_total_away: int = Field(alias="openingstotalaway")
110-
openings_total_home: int = Field(alias="openingstotalhome")
111-
openings_total_lost: int = Field(alias="openingstotallost")
112-
games_total: int = Field(alias="gamestotal")
113-
games_away_total: int = Field(alias="gamesawaytotal")
114-
games_home_total: int = Field(alias="gameshometotal")
108+
openings_total: int = Field(alias="openingsTotal")
109+
openings_total_away: int = Field(alias="openingsTotalAway")
110+
openings_total_home: int = Field(alias="openingsTotalHome")
111+
openings_total_lost: int = Field(alias="openingsTotalLost")
112+
games_total: int = Field(alias="gamesTotal")
113+
games_away_total: int = Field(alias="gamesAwayTotal")
114+
games_home_total: int = Field(alias="gamesHomeTotal")
115115
year: str
116-
attendance_average_ytd: int = Field(alias="attendanceaverageytd")
117-
game_type: AttendanceGameType = Field(alias="gametype")
116+
attendance_average_ytd: int = Field(alias="attendanceAverageYtd")
117+
game_type: AttendanceGameType = Field(alias="gameType")
118118
team: Team
119-
attendance_total: Optional[int] = Field(default=None, alias="attendancetotal")
120-
attendance_average_away: Optional[int] = Field(default=None, alias="attendanceaverageaway")
121-
attendance_average_home: Optional[int] = Field(default=None, alias="attendanceaveragehome")
122-
attendance_high: Optional[int] = Field(default=None, alias="attendancehigh")
123-
attendance_high_date: Optional[str] = Field(default=None, alias="attendancehighdate")
124-
attendance_high_game: Optional[AttendanceHighLowGame] = Field(default=None, alias="attendancehighgame")
125-
attendance_low: Optional[int] = Field(default=None, alias="attendancelow")
126-
attendance_low_date: Optional[str] = Field(default=None, alias="attendancelowdate")
127-
attendance_low_game: Optional[AttendanceHighLowGame] = Field(default=None, alias="attendancelowgame")
128-
attendance_total_away: Optional[int] = Field(default=None, alias="attendancetotalaway")
129-
attendance_total_home: Optional[int] = Field(default=None, alias="attendancetotalhome")
130-
attendance_opening_average: Optional[int] = Field(default=None, alias="attendanceopeningaverage")
119+
attendance_total: Optional[int] = Field(default=None, alias="attendanceTotal")
120+
attendance_average_away: Optional[int] = Field(default=None, alias="attendanceAverageAway")
121+
attendance_average_home: Optional[int] = Field(default=None, alias="attendanceAverageHome")
122+
attendance_high: Optional[int] = Field(default=None, alias="attendanceHigh")
123+
attendance_high_date: Optional[str] = Field(default=None, alias="attendanceHighDate")
124+
attendance_high_game: Optional[AttendanceHighLowGame] = Field(default=None, alias="attendanceHighGame")
125+
attendance_low: Optional[int] = Field(default=None, alias="attendanceLow")
126+
attendance_low_date: Optional[str] = Field(default=None, alias="attendanceLowDate")
127+
attendance_low_game: Optional[AttendanceHighLowGame] = Field(default=None, alias="attendanceLowGame")
128+
attendance_total_away: Optional[int] = Field(default=None, alias="attendanceTotalAway")
129+
attendance_total_home: Optional[int] = Field(default=None, alias="attendanceTotalHome")
130+
attendance_opening_average: Optional[int] = Field(default=None, alias="attendanceOpeningAverage")
131131

132132

133133
class AttendanceTotals(MLBBaseModel):
@@ -161,15 +161,15 @@ class AttendanceTotals(MLBBaseModel):
161161
attendance_total_home : int
162162
Attendance total home.
163163
"""
164-
openings_total_away: int = Field(alias="openingstotalaway")
165-
openings_total_home: int = Field(alias="openingstotalhome")
166-
openings_total_lost: int = Field(alias="openingstotallost")
167-
openings_total_ytd: int = Field(alias="openingstotalytd")
168-
attendance_average_ytd: int = Field(alias="attendanceaverageytd")
169-
attendance_high: int = Field(alias="attendancehigh")
170-
attendance_high_date: str = Field(alias="attendancehighdate")
171-
attendance_total: int = Field(alias="attendancetotal")
172-
attendance_total_away: int = Field(alias="attendancetotalaway")
173-
attendance_total_home: int = Field(alias="attendancetotalhome")
174-
attendance_average_away: Optional[int] = Field(default=None, alias="attendanceaverageaway")
175-
attendance_average_home: Optional[int] = Field(default=None, alias="attendanceaveragehome")
164+
openings_total_away: int = Field(alias="openingsTotalAway")
165+
openings_total_home: int = Field(alias="openingsTotalHome")
166+
openings_total_lost: int = Field(alias="openingsTotalLost")
167+
openings_total_ytd: int = Field(alias="openingsTotalYtd")
168+
attendance_average_ytd: int = Field(alias="attendanceAverageYtd")
169+
attendance_high: int = Field(alias="attendanceHigh")
170+
attendance_high_date: str = Field(alias="attendanceHighDate")
171+
attendance_total: int = Field(alias="attendanceTotal")
172+
attendance_total_away: int = Field(alias="attendanceTotalAway")
173+
attendance_total_home: int = Field(alias="attendanceTotalHome")
174+
attendance_average_away: Optional[int] = Field(default=None, alias="attendanceAverageAway")
175+
attendance_average_home: Optional[int] = Field(default=None, alias="attendanceAverageHome")

0 commit comments

Comments
 (0)