Skip to content

Commit

Permalink
Merge pull request #615 from Robert-litts/2018-api-update
Browse files Browse the repository at this point in the history
2018 Fantasy Football API Update
  • Loading branch information
cwendt94 authored Jan 7, 2025
2 parents 895ec28 + a717848 commit 107cc52
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 24 deletions.
2 changes: 0 additions & 2 deletions espn_api/base_league.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ def __repr__(self):

def _fetch_league(self, SettingsClass = BaseSettings):
data = self.espn_request.get_league()

self.currentMatchupPeriod = data['status']['currentMatchupPeriod']
self.scoringPeriodId = data['scoringPeriodId']
self.firstScoringPeriod = data['status']['firstScoringPeriod']
Expand All @@ -49,7 +48,6 @@ def _fetch_league(self, SettingsClass = BaseSettings):
def _fetch_draft(self):
'''Creates list of Pick objects from the leagues draft'''
data = self.espn_request.get_league_draft()

# League has not drafted yet
if not data.get('draftDetail', {}).get('drafted'):
return
Expand Down
60 changes: 40 additions & 20 deletions espn_api/requests/espn_requests.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,21 +17,6 @@ class ESPNUnknownError(Exception):
pass


def checkRequestStatus(status: int, cookies=None, league_id=None) -> None:
if cookies is None:
cookies = {}
if league_id is None:
league_id = ""
if status == 401:
raise ESPNAccessDenied(f"League {league_id} cannot be accessed with espn_s2={cookies.get('espn_s2')} and swid={cookies.get('SWID')}")

elif status == 404:
raise ESPNInvalidLeague(f"League {league_id} does not exist")

elif status != 200:
raise ESPNUnknownError(f"ESPN returned an HTTP {status}")


class EspnFantasyRequests(object):
def __init__(self, sport: str, year: int, league_id: int, cookies: dict = None, logger: Logger = None):
if sport not in FANTASY_SPORTS:
Expand All @@ -49,19 +34,54 @@ def __init__(self, sport: str, year: int, league_id: int, cookies: dict = None,
else:
self.LEAGUE_ENDPOINT += "/seasons/" + str(year) + "/segments/0/leagues/" + str(league_id)

def checkRequestStatus(self, status: int, extend: str = "", params: dict = None, headers: dict = None) -> dict:
'''Handles ESPN API response status codes and endpoint format switching'''
if status == 401:
# If the current LEAGUE_ENDPOINT was using the /leagueHistory/ endpoint, switch to "/seasons/" endpoint
if "/leagueHistory/" in self.LEAGUE_ENDPOINT:
base_endpoint = self.LEAGUE_ENDPOINT.split("/leagueHistory/")[0]
self.LEAGUE_ENDPOINT = f"{base_endpoint}/seasons/{self.year}/segments/0/leagues/{self.league_id}"
else:
# If the current LEAGUE_ENDPOINT was using /seasons, switch to the "/leagueHistory/" endpoint
base_endpoint = self.LEAGUE_ENDPOINT.split(f"/seasons/")[0]
self.LEAGUE_ENDPOINT = f"{base_endpoint}/leagueHistory/{self.league_id}?seasonId={self.year}"

#try the alternate endpoint
r = requests.get(self.LEAGUE_ENDPOINT + extend, params=params, headers=headers, cookies=self.cookies)

if r.status_code == 200:
# Return the updated response if alternate works
return r.json()

# If all endpoints failed, raise the corresponding error
raise ESPNAccessDenied(f"League {self.league_id} cannot be accessed with espn_s2={self.cookies.get('espn_s2')} and swid={self.cookies.get('SWID')}")

elif status == 404:
raise ESPNInvalidLeague(f"League {self.league_id} does not exist")

elif status != 200:
raise ESPNUnknownError(f"ESPN returned an HTTP {status}")

# If no issues with the status code, return None
return None

def league_get(self, params: dict = None, headers: dict = None, extend: str = ''):
endpoint = self.LEAGUE_ENDPOINT + extend
r = requests.get(endpoint, params=params, headers=headers, cookies=self.cookies)
checkRequestStatus(r.status_code, cookies=self.cookies, league_id=self.league_id)
alternate_response = self.checkRequestStatus(r.status_code, extend=extend, params=params, headers=headers)


response = alternate_response if alternate_response else r.json()

if self.logger:
self.logger.log_request(endpoint=endpoint, params=params, headers=headers, response=r.json())
return r.json() if self.year > 2017 else r.json()[0]
self.logger.log_request(endpoint=self.LEAGUE_ENDPOINT + extend, params=params, headers=headers, response=response)

return response[0] if isinstance(response, list) else response

def get(self, params: dict = None, headers: dict = None, extend: str = ''):
endpoint = self.ENDPOINT + extend
r = requests.get(endpoint, params=params, headers=headers, cookies=self.cookies)
checkRequestStatus(r.status_code)
self.checkRequestStatus(r.status_code)

if self.logger:
self.logger.log_request(endpoint=endpoint, params=params, headers=headers, response=r.json())
Expand All @@ -73,7 +93,7 @@ def get_league(self):
'view': ['mTeam', 'mRoster', 'mMatchup', 'mSettings', 'mStandings']
}
data = self.league_get(params=params)
return data
return data

def get_pro_schedule(self):
'''Gets the current sports professional team schedules'''
Expand Down
6 changes: 4 additions & 2 deletions tests/football/integration/test_league.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,10 @@ def test_past_league(self):
self.assertEqual(league.nfl_week, 18)

def test_private_league(self):
with self.assertRaises(Exception):
League(368876, 2018)
''' Test for switching to fallback API endpoint for private leagues. Random, incorrect cookies used to force fallback. '''
league = League(368876, 2018, 'AEF1234567890ABCDE1234567890ABCD', '{D0C25A4C-2A0D-4E56-8E7F-20A10B663272}')

self.assertEqual(league.espn_request.LEAGUE_ENDPOINT, "https://lm-api-reads.fantasy.espn.com/apis/v3/games/ffl/leagueHistory/368876?seasonId=2018")

def test_unknown_league(self):
with self.assertRaises(Exception):
Expand Down

0 comments on commit 107cc52

Please sign in to comment.