toddrob99 / mlb-statsapi Goto Github PK
View Code? Open in Web Editor NEWPython wrapper for MLB Stats API
License: GNU General Public License v3.0
Python wrapper for MLB Stats API
License: GNU General Public License v3.0
Query params are startTimecode
and endTimecode
with lower case c
, but required params are listed as startTimeCode
and endTimeCode
with upper case C
.
The API accepts either way, but the wrapper does not make the API call, because it discards unrecognized params if upper case C
is used, and fails required param check if lower case c
is used.
Use force=True for calls to game_diff
endpoint until fix is released.
Seasons endpoint supports season parameter to get info about a given season. The endpoint definition is missing this parameter, so it will always return the current season unless the force option is used.
I'm having some trouble with lookup_player() throwing an exception - I'm using the example code from statsapi/init.py
player = statsapi.lookup_player('nola,')
print(player[0]['id']) #assume only 1 record returned for demo purposes
some other calls are working - for example
print(statsapi.meta('leagueLeaderTypes'))
returns a list of League Leader Types
so, I'm thinking the problem is somewhere in the code maybe in get() or maybe the underlying MLB stats API has changed somehow. It's taking me a while to try to figure this out on my own so any help would be appreciated.
Hi there,
Thank you so much for this module. I really enjoy using it.
Wondering if you could tell me which endpoint contains inning related data i.e. number of outs, current batter, type of hit (single vs. double, etc.)
Thanks so much
I found this wrapper and I've really enjoyed using it so far. However, I was curious as to why there is no base running data (i.e CS and SB) for each game in the game's boxscore. The boxscores look identical to the ones on MLB At Bat, just without the base running data.
First off, thank you for this app, it's exactly what I was looking for to display my SF Giants stats on my TV dashboard. I thought I could use the next_game function to show scores as the game is played (since it has a spot for home/away scores). But that doesn't appear to be the case. Is there an easy way to get the current game ID to pass to the one of the other game stats functions? Thanks again!
File "/usr/local/lib/python3.9/site-packages/statsapi/init.py", line 749, in boxscore_data
boxData[side]["players"]["ID" + pitcherId]["stats"]["pitching"][
KeyError: 'pitchesThrown'
#!/usr/bin/env python3
import statsapi
import json
games = statsapi.schedule(start_date='04/08/2022',end_date='10/30/2022', team="145")
for i in games:
box = statsapi.boxscore_data(i['game_id'], timecode=None)
The awards and draft endpoints have path parameters with leading slashes, and the leading slash endpoint configuration setting is not being honored. This results in 404 errors when attempting to use these endpoints.
>>> statsapi.get('awards',{'awardId':'NLMVP'})
2019-11-05 21:04:24,561 - DEBUG - statsapi(10988) - URL: https://statsapi.mlb.com/api/{ver}/awards{awardId}{recipients}
2019-11-05 21:04:24,564 - DEBUG - statsapi(10988) - Found path param: awardId
2019-11-05 21:04:24,564 - DEBUG - statsapi(10988) - path_params: {'awardId': 'NLMVP'}
2019-11-05 21:04:24,565 - DEBUG - statsapi(10988) - query_params: {}
2019-11-05 21:04:24,565 - DEBUG - statsapi(10988) - Replacing {awardId}
2019-11-05 21:04:24,565 - DEBUG - statsapi(10988) - URL: https://statsapi.mlb.com/api/{ver}/awardsNLMVP{recipients}
2019-11-05 21:04:24,566 - DEBUG - statsapi(10988) - Replacing {ver} with default: v1.
2019-11-05 21:04:24,566 - DEBUG - statsapi(10988) - URL: https://statsapi.mlb.com/api/v1/awardsNLMVP{recipients}
2019-11-05 21:04:24,566 - DEBUG - statsapi(10988) - Removing optional param {recipients}
2019-11-05 21:04:24,567 - DEBUG - statsapi(10988) - URL: https://statsapi.mlb.com/api/v1/awardsNLMVP
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\Python37\lib\site-packages\statsapi\__init__.py", line 2453, in get
raise ValueError("Request failed. Status Code: " + str(r.status_code) + ".")
ValueError: Request failed. Status Code: 404.
>>> statsapi.get('draft',{})
2019-11-05 21:05:57,121 - DEBUG - statsapi(10988) - URL: https://statsapi.mlb.com/api/{ver}/draft{prospects}{year}{latest}
2019-11-05 21:05:57,121 - DEBUG - statsapi(10988) - path_params: {}
2019-11-05 21:05:57,122 - DEBUG - statsapi(10988) - query_params: {}
2019-11-05 21:05:57,122 - DEBUG - statsapi(10988) - Replacing {ver} with default: v1.
2019-11-05 21:05:57,153 - DEBUG - statsapi(10988) - URL: https://statsapi.mlb.com/api/v1/draft{prospects}{year}{latest}
2019-11-05 21:05:57,153 - DEBUG - statsapi(10988) - Removing optional param {prospects}
2019-11-05 21:05:57,153 - DEBUG - statsapi(10988) - URL: https://statsapi.mlb.com/api/v1/draft{year}{latest}
2019-11-05 21:05:57,185 - DEBUG - statsapi(10988) - Replacing {year} with default: 2019.
2019-11-05 21:05:57,252 - DEBUG - statsapi(10988) - URL: https://statsapi.mlb.com/api/v1/draft2019{latest}
2019-11-05 21:05:57,253 - DEBUG - statsapi(10988) - Removing optional param {latest}
2019-11-05 21:05:57,253 - DEBUG - statsapi(10988) - URL: https://statsapi.mlb.com/api/v1/draft2019
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\Python37\lib\site-packages\statsapi\__init__.py", line 2453, in get
raise ValueError("Request failed. Status Code: " + str(r.status_code) + ".")
ValueError: Request failed. Status Code: 404.
Setting statsapi.DEBUG to True will result in debug info being printed to console. Instead this should be handled through the logging module.
When pulling from the STATS endpoint, it has a default limit of 50 records. Adding a note for the STATS endpoint to declare the default 50 record limit will help clarify returned data.
MLB documentation says rosterType and season are required for the team_roster endpoint, but the endpoint works fine without them. Remove the requirements.
Call rejected due to missing required parameters:
>>> statsapi.get('team_roster', {'teamId':143})
2019-11-05 21:09:51,345 - DEBUG - statsapi(10988) - URL: https://statsapi.mlb.com/api/{ver}/teams/{teamId}/roster
2019-11-05 21:09:51,345 - DEBUG - statsapi(10988) - Found path param: teamId
2019-11-05 21:09:51,346 - DEBUG - statsapi(10988) - path_params: {'teamId': '143'}
2019-11-05 21:09:51,346 - DEBUG - statsapi(10988) - query_params: {}
2019-11-05 21:09:51,404 - DEBUG - statsapi(10988) - Replacing {teamId}
2019-11-05 21:09:51,404 - DEBUG - statsapi(10988) - URL: https://statsapi.mlb.com/api/{ver}/teams/143/roster
2019-11-05 21:09:51,514 - DEBUG - statsapi(10988) - Replacing {ver} with default: v1.
2019-11-05 21:09:51,517 - DEBUG - statsapi(10988) - URL: https://statsapi.mlb.com/api/v1/teams/143/roster
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\Python37\lib\site-packages\statsapi\__init__.py", line 2447, in get
+ note
ValueError: Missing required parameter(s): rosterType, season.
--Required parameters for the team_roster endpoint: [['rosterType', 'season']].
--Note: If there are multiple sets in the required parameter list, you can choose any of the sets.
Same call forced through and successfully returning results:
>>> statsapi.get('team_roster', {'teamId':143}, force=True)
2019-11-05 21:09:06,039 - DEBUG - statsapi(10988) - URL: https://statsapi.mlb.com/api/{ver}/teams/{teamId}/roster
2019-11-05 21:09:06,039 - DEBUG - statsapi(10988) - Found path param: teamId
2019-11-05 21:09:06,040 - DEBUG - statsapi(10988) - path_params: {'teamId': '143'}
2019-11-05 21:09:06,040 - DEBUG - statsapi(10988) - query_params: {}
2019-11-05 21:09:06,070 - DEBUG - statsapi(10988) - Replacing {teamId}
2019-11-05 21:09:06,070 - DEBUG - statsapi(10988) - URL: https://statsapi.mlb.com/api/{ver}/teams/143/roster
2019-11-05 21:09:06,071 - DEBUG - statsapi(10988) - Replacing {ver} with default: v1.
2019-11-05 21:09:06,103 - DEBUG - statsapi(10988) - URL: https://statsapi.mlb.com/api/v1/teams/143/roster
{'copyright': 'Copyright 2019 MLB Advanced Media, L.P. Use of any content on this page acknowledges agreement to the terms posted here http://gdx.mlb.com/components/copyright.txt', 'roster': [{'person': {'id': 605400, 'fullName': 'Aaron Nola', 'link': '/api/v1/people/605400'}, 'jerseyNumber': '27', 'position': {'code': '1', 'name': 'Pitcher', 'type': 'Pitcher', 'abbreviation': 'P'}, 'status': {'code': 'A', 'description': 'Active'}, 'parentTeamId': 143}, {'person': {'id': 656514, 'fullName': 'Adam Haseley', 'link': '/api/v1/people/656514'}, 'jerseyNumber': '40', 'position': {'code': '8', 'name': 'Outfielder', 'type': 'Outfielder', 'abbreviation': 'CF'}, 'status': {'code': 'A', 'description': 'Active'}, 'parentTeamId': 143}, {'person': {'id': 605388, 'fullName': 'Adam Morgan', 'link': '/api/v1/people/605388'}, 'jerseyNumber': '46', 'position': {'code': '1', 'name': 'Pitcher', 'type': 'Pitcher', 'abbreviation': 'P'}, 'status': {'code': 'A', 'description': 'Active'}, 'parentTeamId': 143}, {'person': {'id': 595284, 'fullName': 'Andrew Knapp', 'link': '/api/v1/people/595284'}, 'jerseyNumber': '15', 'position': {'code': '2', 'name': 'Catcher', 'type': 'Catcher', 'abbreviation': 'C'}, 'status': {'code': 'A', 'description': 'Active'}, 'parentTeamId': 143}, {'person': {'id': 457705, 'fullName': 'Andrew McCutchen', 'link':
'/api/v1/people/457705'}, 'jerseyNumber': '22', 'position': {'code': '7', 'name': 'Outfielder', 'type': 'Outfielder', 'abbreviation': 'LF'}, 'status': {'code': 'A', 'description': 'Active'}, 'parentTeamId': 143}, {'person': {'id': 660614, 'fullName': 'Arquimedes Gamboa', 'link': '/api/v1/people/660614'}, 'jerseyNumber': '70', 'position': {'code': '6', 'name': 'Shortstop', 'type': 'Infielder', 'abbreviation': 'SS'}, 'status': {'code': 'A', 'description': 'Active'}, 'parentTeamId': 143}, {'person': {'id': 656354, 'fullName': 'Austin Davis', 'link': '/api/v1/people/656354'}, 'jerseyNumber': '54', 'position': {'code': '1', 'name': 'Pitcher', 'type': 'Pitcher', 'abbreviation': 'P'}, 'status': {'code': 'A', 'description': 'Active'}, 'parentTeamId': 143}, {'person': {'id': 547180, 'fullName': 'Bryce Harper', 'link': '/api/v1/people/547180'}, 'jerseyNumber': '3', 'position': {'code': '9', 'name': 'Outfielder', 'type': 'Outfielder', 'abbreviation': 'RF'}, 'status': {'code': 'A', 'description': 'Active'}, 'parentTeamId': 143}, {'person': {'id': 514917, 'fullName': 'Cesar Hernandez', 'link': '/api/v1/people/514917'}, 'jerseyNumber': '16', 'position': {'code': '4', 'name': 'Second Base', 'type': 'Infielder', 'abbreviation': '2B'}, 'status': {'code': 'A', 'description': 'Active'}, 'parentTeamId': 143}, {'person': {'id': 608344, 'fullName': 'Cole Irvin', 'link': '/api/v1/people/608344'}, 'jerseyNumber': '47', 'position': {'code': '1', 'name': 'Pitcher', 'type': 'Pitcher', 'abbreviation': 'P'}, 'status': {'code': 'A', 'description': 'Active'}, 'parentTeamId': 143}, {'person': {'id': 502085, 'fullName': 'David Robertson', 'link': '/api/v1/people/502085'}, 'jerseyNumber': '30', 'position': {'code': '1', 'name': 'Pitcher', 'type': 'Pitcher', 'abbreviation': 'P'}, 'status': {'code': 'A', 'description': 'Active'}, 'parentTeamId': 143}, {'person': {'id': 620453, 'fullName': 'Deivy Grullon', 'link': '/api/v1/people/620453'}, 'jerseyNumber': '73', 'position': {'code': '2', 'name': 'Catcher', 'type': 'Catcher', 'abbreviation': 'C'}, 'status': {'code': 'A', 'description': 'Active'}, 'parentTeamId': 143}, {'person': {'id': 658305, 'fullName': 'Edgar Garcia', 'link': '/api/v1/people/658305'}, 'jerseyNumber': '66', 'position': {'code': '1', 'name': 'Pitcher', 'type': 'Pitcher', 'abbreviation': 'P'}, 'status': {'code': 'A', 'description': 'Active'}, 'parentTeamId': 143}, {'person': {'id':
660853, 'fullName': 'Enyel De Los Santos', 'link': '/api/v1/people/660853'}, 'jerseyNumber': '51', 'position': {'code': '1', 'name': 'Pitcher', 'type': 'Pitcher', 'abbreviation': 'P'}, 'status': {'code': 'A', 'description': 'Active'}, 'parentTeamId': 143}, {'person': {'id': 593576, 'fullName': 'Hector Neris', 'link': '/api/v1/people/593576'}, 'jerseyNumber': '50', 'position': {'code': '1', 'name': 'Pitcher', 'type': 'Pitcher', 'abbreviation': 'P'}, 'status': {'code': 'A', 'description': 'Active'}, 'parentTeamId': 143}, {'person': {'id': 592663, 'fullName': 'J.T. Realmuto', 'link': '/api/v1/people/592663'}, 'jerseyNumber': '10', 'position': {'code': '2', 'name': 'Catcher', 'type': 'Catcher', 'abbreviation': 'C'}, 'status': {'code': 'A', 'description': 'Active'}, 'parentTeamId': 143}, {'person': {'id': 453562, 'fullName': 'Jake Arrieta', 'link': '/api/v1/people/453562'}, 'jerseyNumber': '49', 'position': {'code': '1', 'name': 'Pitcher', 'type': 'Pitcher', 'abbreviation': 'P'}, 'status': {'code': 'A', 'description': 'Active'}, 'parentTeamId': 143}, {'person': {'id': 457803, 'fullName': 'Jay Bruce', 'link': '/api/v1/people/457803'}, 'jerseyNumber': '23', 'position': {'code': '9', 'name': 'Outfielder', 'type': 'Outfielder', 'abbreviation': 'RF'}, 'status': {'code': 'A', 'description': 'Active'}, 'parentTeamId': 143}, {'person': {'id': 670456, 'fullName': 'JD Hammer', 'link': '/api/v1/people/670456'}, 'jerseyNumber': '65', 'position': {'code': '1', 'name': 'Pitcher', 'type': 'Pitcher', 'abbreviation': 'P'}, 'status': {'code': 'A', 'description': 'Active'}, 'parentTeamId': 143}, {'person': {'id': 516416, 'fullName': 'Jean Segura', 'link': '/api/v1/people/516416'}, 'jerseyNumber': '2', 'position': {'code': '6', 'name': 'Shortstop', 'type': 'Infielder', 'abbreviation': 'SS'}, 'status': {'code': 'A', 'description': 'Active'}, 'parentTeamId': 143}, {'person': {'id': 501625, 'fullName': 'Jose Alvarez', 'link': '/api/v1/people/501625'}, 'jerseyNumber': '52', 'position': {'code': '1', 'name': 'Pitcher', 'type': 'Pitcher', 'abbreviation': 'P'}, 'status': {'code': 'A', 'description': 'Active'}, 'parentTeamId': 143}, {'person': {'id': 596748, 'fullName': 'Maikel Franco', 'link': '/api/v1/people/596748'}, 'jerseyNumber': '7', 'position': {'code': '5', 'name': 'Third Base', 'type': 'Infielder', 'abbreviation': '3B'}, 'status': {'code': 'A', 'description': 'Active'}, 'parentTeamId': 143}, {'person': {'id': 601713, 'fullName': 'Nick Pivetta', 'link': '/api/v1/people/601713'}, 'jerseyNumber': '43', 'position': {'code': '1', 'name': 'Pitcher', 'type': 'Pitcher', 'abbreviation': 'P'}, 'status': {'code': 'A', 'description': 'Active'}, 'parentTeamId': 143}, {'person': {'id': 608384, 'fullName': 'Nick Williams', 'link': '/api/v1/people/608384'}, 'jerseyNumber': '5', 'position': {'code': '7', 'name': 'Outfielder', 'type': 'Outfielder', 'abbreviation': 'LF'}, 'status': {'code': 'A', 'description': 'Active'}, 'parentTeamId': 143}, {'person': {'id': 546318, 'fullName': 'Odubel Herrera', 'link': '/api/v1/people/546318'}, 'jerseyNumber': '37', 'position': {'code': '8', 'name': 'Outfielder', 'type': 'Outfielder', 'abbreviation': 'CF'}, 'status': {'code': 'A', 'description': 'Active'}, 'parentTeamId': 143}, {'person': {'id': 624133, 'fullName': 'Ranger Suarez', 'link': '/api/v1/people/624133'}, 'jerseyNumber': '55', 'position': {'code': '1', 'name': 'Pitcher', 'type': 'Pitcher', 'abbreviation': 'P'}, 'status': {'code': 'A', 'description': 'Active'}, 'parentTeamId': 143}, {'person': {'id': 656555, 'fullName': 'Rhys Hoskins', 'link': '/api/v1/people/656555'}, 'jerseyNumber': '17', 'position': {'code': '3', 'name': 'First Base', 'type': 'Infielder', 'abbreviation': '1B'}, 'status': {'code': 'A', 'description': 'Active'}, 'parentTeamId': 143}, {'person': {'id': 476594, 'fullName': 'Robert Stock', 'link': '/api/v1/people/476594'}, 'jerseyNumber': '', 'position': {'code': '1', 'name': 'Pitcher', 'type': 'Pitcher', 'abbreviation': 'P'}, 'status': {'code': 'A', 'description': 'Active'}, 'parentTeamId': 143}, {'person': {'id': 596451, 'fullName': 'Roman Quinn', 'link': '/api/v1/people/596451'}, 'jerseyNumber': '24', 'position': {'code': '8', 'name': 'Outfielder', 'type': 'Outfielder', 'abbreviation': 'CF'}, 'status': {'code': 'A', 'description': 'Active'}, 'parentTeamId': 143}, {'person': {'id': 664068, 'fullName': 'Scott Kingery', 'link': '/api/v1/people/664068'}, 'jerseyNumber': '4', 'position': {'code': '8', 'name': 'Outfielder', 'type': 'Outfielder', 'abbreviation': 'CF'}, 'status': {'code': 'A', 'description': 'Active'}, 'parentTeamId': 143}, {'person': {'id': 622554, 'fullName': 'Seranthony Dominguez', 'link': '/api/v1/people/622554'}, 'jerseyNumber': '58', 'position': {'code': '1', 'name': 'Pitcher', 'type': 'Pitcher', 'abbreviation': 'P'}, 'status': {'code': 'A', 'description': 'Active'}, 'parentTeamId': 143}, {'person': {'id': 644364, 'fullName': 'Victor Arano', 'link': '/api/v1/people/644364'}, 'jerseyNumber': '64', 'position': {'code': '1', 'name': 'Pitcher', 'type': 'Pitcher', 'abbreviation': 'P'}, 'status': {'code': 'A', 'description': 'Active'}, 'parentTeamId': 143}, {'person': {'id': 592826, 'fullName': 'Vince Velasquez', 'link': '/api/v1/people/592826'}, 'jerseyNumber': '21', 'position': {'code': '1', 'name': 'Pitcher', 'type': 'Pitcher', 'abbreviation': 'P'}, 'status': {'code': 'A', 'description': 'Active'}, 'parentTeamId': 143}, {'person': {'id': 621107, 'fullName': 'Zach Eflin', 'link': '/api/v1/people/621107'}, 'jerseyNumber': '56', 'position': {'code': '1', 'name': 'Pitcher', 'type': 'Pitcher', 'abbreviation': 'P'}, 'status': {'code': 'A', 'description': 'Active'}, 'parentTeamId': 143}], 'link': '/api/v1/teams/143/roster', 'teamId': 143, 'rosterType': 'active'}
Is there a good way to get the information one would need to draw a bracket? Something like:
Let's assume for starters I want to do it at the conclusion of a season/for a past season.
Something like (I can obviously handle the drawing, more of a data question - none of the endpoints seem to be ideal for this):
WC 2 -----|
|--- Winner ---|
WC 1 -----| | --- Winner ---|
1 seed ---| |
| NL Champ
2 seed ---| |
| --- Winner ---|
3 seed ---|
The following fields are missing from the header row records in the return data from boxscore_data():
Batters: battingOrder
Pitchers: p, s
After #22 has been implemented, it would be beneficial to cleanup the package init.py as well as the endpoints.py. For easier readability as well as interfacing in third party programs. Beyond formatting, it would be nicer to implement a better interface, currently a majority of the functions return formatted strings with the data from the API, instead of returning JSON.
Ideas:
You don't have an email or twitter, but wanted to drop in and say thank you for your excellent work here. I'm building a batteries-included Rust version for the Stats API and your repo has been invaluable in finding all the niche "hydrations" and other details that I'd otherwise have to find by trial and error.
I am trying to grab the league standings for the National League East only and I can not figure out the value for division to put in
print(statsapi.standings(leagueId=104, date='05/12/2019'))
Thank you in advance! Go Phils!!
'teamCode' for this call (statsapi.lookup_team('San Fransisco Giants')) is SFN instead of SFG - can you explain why that is?
i was going through some of the code in the documentation:
this line of code:
print( statsapi.league_leaders('onBasePlusSlugging',statGroup='hitting',limit=5) )
gives:
IndexError: list index out of range
I am personally unable to find the gamePk parameter documentation.
Steps to recreate:
call statsapi.player_stat_data( 592622, group="hitting", type="season") for player Mark Payton with id 592622
Data can be seen directly at https://statsapi.mlb.com/api/v1/people/592622?hydrate=stats(group=hitting,type=season),currentTeam
Expected result:
Data returned
Actual result:
File "/home/mycarda/.local/lib/python2.7/site-packages/statsapi/init.py", line 1123, in player_stat_data
"mlb_debut": r["people"][0]["mlbDebutDate"],
KeyError: 'mlbDebutDate'
https://www.reddit.com/r/mlbdata/comments/rm9abd/new_stats_api_transaction_endpoint_exposed/
https://statsapi.mlb.com/api/v1/transactions
Parameters: teamId, playerId, date, startDate, endDate.
Date, startDate and endDate use the following date format: YYYY-MM-DD.
Pretty self explanatory. I want to be able to know if there is a runner on first, second, third, etc.
The following is a valid url for the api:
http://statsapi.mlb.com/api/v1/teams/145/stats?stats=yearByYear&group=hitting
But if I try running the python wrapper equivalent -
mlb.get("team_stats",{"teamId":145,"stats":"yearByYear","group":hitting})
I receive the following error -
ValueError: Missing required parameter(s): season.
I reckon that the "season" parameter is only required when retrieving a statType that doesn't need a specific season given. The statTypes - "yearByYear" and "yearByYearAdvanced" are at least two of them that don't require this parameter. There might be more but I have not looked yet.
Were these originally determined through trial and error, or is there somewhere I can go for more information about how to use these parameters for different endpoints?
I'm getting all game_ids to pull boxscores from older seasons, and am using the statsapi.schedule function per the minimum example below. This throws an error shown below where 'score' isn't recognized. This code works for 2010 season and 2012-current seasons...just 2011. Anyone know the fix?
import statsapi games = statsapi.schedule(start_date = '03/30/2011', end_date = '10/28/2011')
Hi there -- is there a way to pull data on an inning level from pitchers? I want to look at recent 30 inning data for a bunch of pitchers, but the best method I can think of is to use the game_playByPlay endpoint and try to manually calculate all the stats. Is there a better method?
I noticed that if I call StatsAPI's get
method and the server returns a 5xx error, the StatsAPI code raise a ValueError
.
Would you be open to allowing Requests to raise an HTTPError
instead? It's directly supported by the Requests API:
r.raise_for_status()
I think that the HTTPError
would make it more clear to callers what went wrong. If it sounds good I'll send a small pull request.
https://statsapi.mlb.com/api/v1/schedule?sportId=1&teamId=147 returns zero items
https://statsapi.mlb.com/api/v1/schedule?sportId=1&teamId=147&season=2021 returns the proper result
Others:
NY Mets - Two most recent completed games
LA Angels - Most recent completed game
SWB RailRiders (Yankees AAA affiliate) - Zero items (sportId = 11)
All return what should be correct responses when adding season=2021 parameter
I was iterating through games of the 2016 season and saw that when I tried to call boxscore_data() on gamepk 448650 it failed with "KeyError: inningsPitched." Not sure what's causing the issue but wanted to bring it to someone's attention.
Outside of this the library has been a lot of fun to mess around with season statistics :) keep up the great work!
I got the following error when trying to get information on a game that was postponed:
line 148, in schedule 'current_inning': game['linescore'].get('currentInning',''), KeyError: 'linescore'
Here's the code I used to generate this error:
game_day = statsapi.schedule(team=136,start_date='05/11/2018')
Another postponed date that throws a different error is 04/08/2018.
Implement standard code formatting using black
Endpoint stats_streaks requires sportId and limit
Hi there. Not an issue, just a question. I'm fairly new to python and to this API but I'm having a bit of trouble pulling in the career WAR / full season WAR for a given player. I know WAR is a field in the meta, but for some reason when I pull career stats for a given player with the 'player_stats' command I'm not seeing WAR in the output. Any help would be appreciated!
statsapi.boxscore_data(564949)
results in KeyError: 'pitchesThrown'
Anyone run into this?
Hi - I'm trying to compile previous season stats by looking up player id using the player_stat_data, but the stats value on that lookup is always empty. I have data on a game by game basis but don't want to manually calculate that
Minimum Example:
statsapi.player_stat_data('645277', group="hitting", type = 'season')
NOTE: type = 'career' does work but that isn't what is needed.
return this object. Note how 'stats' is just an empty list
{'id': 645277,
'first_name': 'Ozzie',
'last_name': 'Albies',
'active': True,
'current_team': 'Atlanta Braves',
'position': '2B',
'nickname': 'Bolly',
'last_played': None,
'mlb_debut': '2017-08-01',
'bat_side': 'Switch',
'pitch_hand': 'Right',
'stats': []}
Tried the example provided in the wiki and got this KeyError exception. However, if I tried other gamePks like statsapi.game_highlights(statsapi.last_game(144)), it seems working. Do we know what might cause this issue?
This could be an issue on my end but figured I would mention it just in case. When looping through dates my code will stop with an error like this:
line 145, in schedule 'away_pitcher_note': game['teams']['away'].get('probablePitcher').get('note',''),
AttributeError: 'NoneType' object has no attribute 'get'
This only happens with certain dates and after testing it seems to be pretty random. Here is what my code looks like (changing end_date to 03/23/2019 will return an error for me).
for x in statsapi.schedule(start_date='03/20/2019',end_date='03/21/2019'):
if (x['status'] in ['Final','Game Over'] and x['game_type'] in ['R']):
print(x['game_id'])
else:
pass
Could there be a format for the box score1 that places the teams one under the other. if the terminal pane isn't wide enough a format that shows the team results stacked vertically instead of horizontally is needed.
Please consider adding the details for the Venue to the schedule method. I've submitted PR #41.
looks like it exists under playByPlay using different terms.
seriously considering just porting the old perl code to parse the json and update the tuples for 2019-2020, since i had to do some to get the games for each day.
will probably do it when i enter the 2021 data, then i'll retrospectively update the old data with this new approach (2019-2020). maybe just update existing entries with this data.
pulling the xml-based stuff anyways (2021, already entering 2020 >_>).
annoying af. i don't see the benefits. maybe json is tighter than xml. less files sure (probably storage savings too), but the tuples don't seem particularly more informative than before.
my hope is that parsing json in perl will be much faster than xml. it very well may be.
Not sure how this would even be used without access to the gamePk but the home run derby endpoint has a typo - url reads \honeRunDerby\
when it should read \homeRunDerby\
It'd be nice to have the option of getting leagueRank
and sportRank
when getting standings, but right now standings_data
doesn't even pull that data. Having it in standings
—perhaps with a flag or only when getting just one league/the whole sport—would be ideal, but at a minimum making it available via standings_data
would be fine.
The teams_stats
endpoint supports startDate
and endDate
query parameters, but they are missing from the endpoint config.
>>> a = statsapi.get('teams_stats', {'group':'hitting', 'season':2019, 'sportIds': 1, 'stats':'byDateRange', 'startDate':'07/01/2019', 'endDate': '07/31/2019'})
2020-07-01 21:26:29,519 - DEBUG - statsapi(21816) - URL: https://statsapi.mlb.com/api/{ver}/teams/stats
2020-07-01 21:26:29,520 - DEBUG - statsapi(21816) - Found query param: group
2020-07-01 21:26:29,520 - DEBUG - statsapi(21816) - Found query param: season
2020-07-01 21:26:29,520 - DEBUG - statsapi(21816) - Found query param: sportIds
2020-07-01 21:26:29,520 - DEBUG - statsapi(21816) - Found query param: stats
2020-07-01 21:26:29,520 - DEBUG - statsapi(21816) - Found invalid param, ignoring: startDate
2020-07-01 21:26:29,521 - DEBUG - statsapi(21816) - Found invalid param, ignoring: endDate
2020-07-01 21:26:29,521 - DEBUG - statsapi(21816) - path_params: {}
2020-07-01 21:26:29,521 - DEBUG - statsapi(21816) - query_params: {'group': 'hitting', 'season': '2019', 'sportIds': '1', 'stats': 'byDateRange'}
2020-07-01 21:26:29,521 - DEBUG - statsapi(21816) - Replacing {ver} with default: v1.
2020-07-01 21:26:29,522 - DEBUG - statsapi(21816) - URL: https://statsapi.mlb.com/api/v1/teams/stats
2020-07-01 21:26:29,522 - DEBUG - statsapi(21816) - Adding query parameter group=hitting
2020-07-01 21:26:29,522 - DEBUG - statsapi(21816) - URL: https://statsapi.mlb.com/api/v1/teams/stats?group=hitting
2020-07-01 21:26:29,522 - DEBUG - statsapi(21816) - Adding query parameter season=2019
2020-07-01 21:26:29,522 - DEBUG - statsapi(21816) - URL: https://statsapi.mlb.com/api/v1/teams/stats?group=hitting&season=2019
2020-07-01 21:26:29,523 - DEBUG - statsapi(21816) - Adding query parameter sportIds=1
2020-07-01 21:26:29,523 - DEBUG - statsapi(21816) - URL: https://statsapi.mlb.com/api/v1/teams/stats?group=hitting&season=2019&sportIds=1
2020-07-01 21:26:29,523 - DEBUG - statsapi(21816) - Adding query parameter stats=byDateRange
2020-07-01 21:26:29,523 - DEBUG - statsapi(21816) - URL: https://statsapi.mlb.com/api/v1/teams/stats?group=hitting&season=2019&sportIds=1&stats=byDateRange
2020-07-01 21:26:29,531 - DEBUG - urllib3.connectionpool(21816) - Starting new HTTPS connection (1): statsapi.mlb.com:443
2020-07-01 21:26:29,716 - DEBUG - urllib3.connectionpool(21816) - https://statsapi.mlb.com:443 "GET /api/v1/teams/stats?group=hitting&season=2019&sportIds=1&stats=byDateRange HTTP/1.1" 200 None
Workaround is to use the force parameter when calling the teams_stats endpoint using stat type of byDateRange
:
>>> a = statsapi.get('teams_stats', {'group':'hitting', 'season':2019, 'sportIds': 1, 'stats':'byDateRange', 'startDate':'07/01/2019', 'endDate': '07/31/2019'}, force=True)
2020-07-01 21:26:52,488 - DEBUG - statsapi(21816) - URL: https://statsapi.mlb.com/api/{ver}/teams/stats
2020-07-01 21:26:52,488 - DEBUG - statsapi(21816) - Found query param: group
2020-07-01 21:26:52,488 - DEBUG - statsapi(21816) - Found query param: season
2020-07-01 21:26:52,489 - DEBUG - statsapi(21816) - Found query param: sportIds
2020-07-01 21:26:52,489 - DEBUG - statsapi(21816) - Found query param: stats
2020-07-01 21:26:52,489 - DEBUG - statsapi(21816) - Found invalid param, forcing into query parameters per force flag: startDate
2020-07-01 21:26:52,489 - DEBUG - statsapi(21816) - Found invalid param, forcing into query parameters per force flag: endDate
2020-07-01 21:26:52,489 - DEBUG - statsapi(21816) - path_params: {}
2020-07-01 21:26:52,490 - DEBUG - statsapi(21816) - query_params: {'group': 'hitting', 'season': '2019', 'sportIds': '1', 'stats': 'byDateRange', 'startDate': '07/01/2019', 'endDate': '07/31/2019'}
2020-07-01 21:26:52,490 - DEBUG - statsapi(21816) - Replacing {ver} with default: v1.
2020-07-01 21:26:52,490 - DEBUG - statsapi(21816) - URL: https://statsapi.mlb.com/api/v1/teams/stats
2020-07-01 21:26:52,490 - DEBUG - statsapi(21816) - Adding query parameter group=hitting
2020-07-01 21:26:52,490 - DEBUG - statsapi(21816) - URL: https://statsapi.mlb.com/api/v1/teams/stats?group=hitting
2020-07-01 21:26:52,491 - DEBUG - statsapi(21816) - Adding query parameter season=2019
2020-07-01 21:26:52,491 - DEBUG - statsapi(21816) - URL: https://statsapi.mlb.com/api/v1/teams/stats?group=hitting&season=2019
2020-07-01 21:26:52,491 - DEBUG - statsapi(21816) - Adding query parameter sportIds=1
2020-07-01 21:26:52,491 - DEBUG - statsapi(21816) - URL: https://statsapi.mlb.com/api/v1/teams/stats?group=hitting&season=2019&sportIds=1
2020-07-01 21:26:52,492 - DEBUG - statsapi(21816) - Adding query parameter stats=byDateRange
2020-07-01 21:26:52,492 - DEBUG - statsapi(21816) - URL: https://statsapi.mlb.com/api/v1/teams/stats?group=hitting&season=2019&sportIds=1&stats=byDateRange
2020-07-01 21:26:52,492 - DEBUG - statsapi(21816) - Adding query parameter startDate=07/01/2019
2020-07-01 21:26:52,492 - DEBUG - statsapi(21816) - URL: https://statsapi.mlb.com/api/v1/teams/stats?group=hitting&season=2019&sportIds=1&stats=byDateRange&startDate=07/01/2019
2020-07-01 21:26:52,492 - DEBUG - statsapi(21816) - Adding query parameter endDate=07/31/2019
2020-07-01 21:26:52,493 - DEBUG - statsapi(21816) - URL: https://statsapi.mlb.com/api/v1/teams/stats?group=hitting&season=2019&sportIds=1&stats=byDateRange&startDate=07/01/2019&endDate=07/31/2019
2020-07-01 21:26:52,496 - DEBUG - urllib3.connectionpool(21816) - Starting new HTTPS connection (1): statsapi.mlb.com:443
2020-07-01 21:26:52,691 - DEBUG - urllib3.connectionpool(21816) - https://statsapi.mlb.com:443 "GET /api/v1/teams/stats?group=hitting&season=2019&sportIds=1&stats=byDateRange&startDate=07/01/2019&endDate=07/31/2019 HTTP/1.1" 200 None
I installed MLB Stats API to my Windows laptop but having issues accessing the API when coding. Any ideas on how to fix the below error?
CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate
I ran the following with version 0.0.8 which was running fine a few weeks ago:
import statsapi
start_date = '2019-03-28'
end_date = '2019-06-25'game_list_2019 = statsapi.schedule(start_date=start_date, end_date=end_date)
And get back this error:
Traceback (most recent call last):
File "C:/Test.py", line 16, in
game_list_2019 = statsapi.schedule(start_date=start_date, end_date=end_date)
File "C:\Users\Philconow\AppData\Local\Programs\Python\Python37\lib\site-packages\statsapi_init_.py", line 161, in schedule
'winning_pitcher': game['decisions'].get('winner',{}).get('fullName',''),
KeyError: 'decisions'
It's possible to get information about where a game is being broadcast from the schedule endpoint:
https://statsapi.mlb.com/api/v1/schedule?sportId=1&date=2022-04-10&hydrate=broadcasts
Especially with all the new services, it would be great to include national broadcasts in the schedule()
method's return data. I don't think non-national would be that valuable, since it will usually be the same network
SALVE THE RIDDAL AND SAVOIR THE SPAWYLZ
The game_scoring_play_data function is not returning any of the expected lists of scoring plays. I checked the response from the mlb api and it doesn't look like the call is returning any plays at all. Maybe the plays from a game have moved somewhere else?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.