swar / nba_api

An API Client package to access the APIs for NBA.com
MIT License
2.54k stars 543 forks source link

[Bug]: playbyplayv3 throws an error when running get_dat_sets() within get_request #433

Open equilibliam opened 8 months ago

equilibliam commented 8 months ago

NBA API Version

1.4.1

Issue

When attempting to fetch play-by-play data using the playbyplayv3.PlayByPlayV3() method from the nba_api library, a TypeError is raised indicating that NBAStatsResponse.get_data_sets() takes 1 positional argument but 2 were given.

Thanks for all the work on this library - it is so so so useful.

Code

import pandas as pd
from nba_api.stats.static import teams
from nba_api.stats.endpoints import playbyplayv3
from nba_api.stats.endpoints import leaguegamefinder
from nba_api.stats.library.parameters import Season
from nba_api.stats.library.parameters import SeasonType
from sqlalchemy import create_engine
# Define a function to fetch play by play data for a game
def fetch_play_by_play(game_id):
    play_by_play_data = playbyplayv3.PlayByPlayV3(game_id)
    play_by_play_data = playbyplaydata.get_data_frames()[0]
    return play_by_play_data

# Define a function to fetch all games in the past 3 years
def fetch_games_past_3_years():
    gamefinder = leaguegamefinder.LeagueGameFinder(season_nullable=Season.default, season_type_nullable=SeasonType.regular)
    all_games = gamefinder.get_data_frames()[0]
    all_games['GAME_DATE'] = pd.to_datetime(all_games['GAME_DATE'])
    three_years_ago = pd.Timestamp.now() - pd.DateOffset(years=5)
    recent_games = all_games[all_games['GAME_DATE'] > three_years_ago]
    return recent_games

# Fetch all games in the past 3 years
recent_games = fetch_games_past_3_years()

# Fetch play by play data for each game and store it in the database
from tqdm import tqdm
for index, game in tqdm(recent_games.iterrows(), total=recent_games.shape[0]):
    game_id = game['GAME_ID']
    play_by_play_data = fetch_play_by_play(game_id)
    play_by_play_data.columns = map(str.lower, play_by_play_data.columns)

    # Store the play by play data in the database
    play_by_play_data.to_sql('play_by_play_v3', engine, if_exists='append', index=False)

Stack trace

   ---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
[/Users/liamgundlach/LBM/curate_nba_game_logs.ipynb](https://file+.vscode-resource.vscode-cdn.net/Users/liamgundlach/LBM/curate_nba_game_logs.ipynb) Cell 4 line 2
     [21](vscode-notebook-cell:/Users/liamgundlach/LBM/curate_nba_game_logs.ipynb#W2sZmlsZQ%3D%3D?line=20) for index, game in tqdm(recent_games.iterrows(), total=recent_games.shape[0]):
     [22](vscode-notebook-cell:/Users/liamgundlach/LBM/curate_nba_game_logs.ipynb#W2sZmlsZQ%3D%3D?line=21)     game_id = game['GAME_ID']
---> [23](vscode-notebook-cell:/Users/liamgundlach/LBM/curate_nba_game_logs.ipynb#W2sZmlsZQ%3D%3D?line=22)     play_by_play_data = fetch_play_by_play(game_id)
     [24](vscode-notebook-cell:/Users/liamgundlach/LBM/curate_nba_game_logs.ipynb#W2sZmlsZQ%3D%3D?line=23)     # play_by_play_data['PLAY_TYPE'] = play_by_play_data['EVENTMSGTYPE'].apply(lambda x: EventMsgType(x).name)
     [25](vscode-notebook-cell:/Users/liamgundlach/LBM/curate_nba_game_logs.ipynb#W2sZmlsZQ%3D%3D?line=24)     play_by_play_data.columns = map(str.lower, play_by_play_data.columns)

[/Users/liamgundlach/LBM/curate_nba_game_logs.ipynb](https://file+.vscode-resource.vscode-cdn.net/Users/liamgundlach/LBM/curate_nba_game_logs.ipynb) Cell 4 line 3
      [2](vscode-notebook-cell:/Users/liamgundlach/LBM/curate_nba_game_logs.ipynb#W2sZmlsZQ%3D%3D?line=1) def fetch_play_by_play(game_id):
----> [3](vscode-notebook-cell:/Users/liamgundlach/LBM/curate_nba_game_logs.ipynb#W2sZmlsZQ%3D%3D?line=2)     play_by_play_data = playbyplayv3.PlayByPlayV3(game_id)
      [4](vscode-notebook-cell:/Users/liamgundlach/LBM/curate_nba_game_logs.ipynb#W2sZmlsZQ%3D%3D?line=3)     play_by_play_data = playbyplaydata.get_data_frames()[0]
      [5](vscode-notebook-cell:/Users/liamgundlach/LBM/curate_nba_game_logs.ipynb#W2sZmlsZQ%3D%3D?line=4)     return play_by_play_data

File [~/anaconda3/lib/python3.11/site-packages/nba_api/stats/endpoints/playbyplayv3.py:63](https://file+.vscode-resource.vscode-cdn.net/Users/liamgundlach/LBM/~/anaconda3/lib/python3.11/site-packages/nba_api/stats/endpoints/playbyplayv3.py:63), in PlayByPlayV3.__init__(self, game_id, end_period, start_period, proxy, headers, timeout, get_request)
     [57](https://file+.vscode-resource.vscode-cdn.net/Users/liamgundlach/LBM/~/anaconda3/lib/python3.11/site-packages/nba_api/stats/endpoints/playbyplayv3.py:57) self.parameters = {
     [58](https://file+.vscode-resource.vscode-cdn.net/Users/liamgundlach/LBM/~/anaconda3/lib/python3.11/site-packages/nba_api/stats/endpoints/playbyplayv3.py:58)     "GameID": game_id,
     [59](https://file+.vscode-resource.vscode-cdn.net/Users/liamgundlach/LBM/~/anaconda3/lib/python3.11/site-packages/nba_api/stats/endpoints/playbyplayv3.py:59)     "EndPeriod": end_period,
     [60](https://file+.vscode-resource.vscode-cdn.net/Users/liamgundlach/LBM/~/anaconda3/lib/python3.11/site-packages/nba_api/stats/endpoints/playbyplayv3.py:60)     "StartPeriod": start_period,
     [61](https://file+.vscode-resource.vscode-cdn.net/Users/liamgundlach/LBM/~/anaconda3/lib/python3.11/site-packages/nba_api/stats/endpoints/playbyplayv3.py:61) }
     [62](https://file+.vscode-resource.vscode-cdn.net/Users/liamgundlach/LBM/~/anaconda3/lib/python3.11/site-packages/nba_api/stats/endpoints/playbyplayv3.py:62) if get_request:
---> [63](https://file+.vscode-resource.vscode-cdn.net/Users/liamgundlach/LBM/~/anaconda3/lib/python3.11/site-packages/nba_api/stats/endpoints/playbyplayv3.py:63)     self.get_request()

File [~/anaconda3/lib/python3.11/site-packages/nba_api/stats/endpoints/playbyplayv3.py:73](https://file+.vscode-resource.vscode-cdn.net/Users/liamgundlach/LBM/~/anaconda3/lib/python3.11/site-packages/nba_api/stats/endpoints/playbyplayv3.py:73), in PlayByPlayV3.get_request(self)
...
     [79](https://file+.vscode-resource.vscode-cdn.net/Users/liamgundlach/LBM/~/anaconda3/lib/python3.11/site-packages/nba_api/stats/endpoints/playbyplayv3.py:79)         for data_set_name, data_set in data_sets.items()
     [80](https://file+.vscode-resource.vscode-cdn.net/Users/liamgundlach/LBM/~/anaconda3/lib/python3.11/site-packages/nba_api/stats/endpoints/playbyplayv3.py:80)     ]
     [81](https://file+.vscode-resource.vscode-cdn.net/Users/liamgundlach/LBM/~/anaconda3/lib/python3.11/site-packages/nba_api/stats/endpoints/playbyplayv3.py:81)     self.available_video = Endpoint.DataSet(data=data_sets["AvailableVideo"])

TypeError: NBAStatsResponse.get_data_sets() takes 1 positional argument but 2 were given
pfredCL commented 8 months ago

I'm experiencing a bug with playbyplayv3 as well, though apparently different than yours.

Actually, I think I've spotted a bug with your code:

def fetch_play_by_play(game_id):
    play_by_play_data = playbyplayv3.PlayByPlayV3(game_id)
    play_by_play_data = playbyplaydata.get_data_frames()[0]
    return play_by_play_data

Specifically in line 2 of the above function, shouldn't the line read: play_by_play_data = play_by_play_data.get_data_frames()[0]

It looks like the error is being thrown a line above that so that might not change anything anyway.

Anyway, this is the error I'm experiencing with the endpoint:

CODE

from nba_api.stats.endpoints import playbyplayv3

pbp = playbyplayv3.PlayByPlayV3(game_id='22201163')
print(pbp.get_data_frames()[0])

ERROR

Traceback (most recent call last):
  File "c:\Users\Owner\Desktop\Code\testPy.py", line 55, in <module>
    play_by_play_data = playbyplayv3.PlayByPlayV3('22201163')
  File "C:\Users\Owner\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.9_qbz5n2kfra8p0\LocalCache\local-packages\Python39\site-packages\nba_api\stats\endpoints\playbyplayv3.py", line 63, in __init__
    self.get_request()
  File "C:\Users\Owner\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.9_qbz5n2kfra8p0\LocalCache\local-packages\Python39\site-packages\nba_api\stats\endpoints\playbyplayv3.py", line 73, in get_request
    self.load_response()
  File "C:\Users\Owner\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.9_qbz5n2kfra8p0\LocalCache\local-packages\Python39\site-packages\nba_api\stats\endpoints\playbyplayv3.py", line 76, in load_response
    data_sets = self.nba_response.get_data_sets(self.endpoint)
  File "C:\Users\Owner\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.9_qbz5n2kfra8p0\LocalCache\local-packages\Python39\site-packages\nba_api\stats\library\http.py", line 150, in get_data_sets
    return endpoint_parser.get_data_sets()
  File "C:\Users\Owner\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.9_qbz5n2kfra8p0\LocalCache\local-packages\Python39\site-packages\nba_api\stats\library\parserv3.py", line 309, in get_data_sets
    pbp_head = self.get_playbyplay_headers()
  File "C:\Users\Owner\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.9_qbz5n2kfra8p0\LocalCache\local-packages\Python39\site-packages\nba_api\stats\library\parserv3.py", line 284, in get_playbyplay_headers
    tmp = self.nba_dict[list(self.nba_dict.keys())[1]]
IndexError: list index out of range

Not sure if they're related but they're both bugs with playbyplayv3 so figured I'd chime in too.

shufinskiy commented 5 months ago

@pfredCL, you need use full game_id:

from nba_api.stats.endpoints import playbyplayv3

pbp = playbyplayv3.PlayByPlayV3(game_id='0022201163')
print(pbp.get_data_frames()[0])
pfredCL commented 5 months ago

@shufinskiy you're a lifesaver, thank you!