From f0de4f3e728d5a5560a3c4ed338959e7298259e0 Mon Sep 17 00:00:00 2001 From: Christian Wendt Date: Thu, 22 Feb 2024 17:27:35 +0000 Subject: [PATCH 1/4] feat: Pull Draft/Pick to Base League and Add for All Sports --- espn_api/base_league.py | 29 +++++++++++++++++ espn_api/{basketball/pick.py => base_pick.py} | 4 +-- espn_api/baseball/league.py | 7 +---- espn_api/basketball/league.py | 31 +------------------ espn_api/football/league.py | 30 +----------------- espn_api/football/pick.py | 18 ----------- espn_api/hockey/league.py | 6 +--- espn_api/wbasketball/league.py | 6 +--- 8 files changed, 36 insertions(+), 95 deletions(-) rename espn_api/{basketball/pick.py => base_pick.py} (89%) delete mode 100644 espn_api/football/pick.py diff --git a/espn_api/base_league.py b/espn_api/base_league.py index f1941f6e..1e26524b 100644 --- a/espn_api/base_league.py +++ b/espn_api/base_league.py @@ -2,6 +2,7 @@ from typing import List, Tuple from .base_settings import BaseSettings +from .base_pick import BasePick from .utils.logger import Logger from .requests.espn_requests import EspnFantasyRequests @@ -45,6 +46,28 @@ def _fetch_league(self, SettingsClass = BaseSettings): self.members = data.get('members', []) return data + 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 + + picks = data.get('draftDetail', {}).get('picks', []) + for pick in picks: + team = self.get_team_data(pick.get('teamId')) + playerId = pick.get('playerId') + playerName = '' + if playerId in self.player_map: + playerName = self.player_map[playerId] + round_num = pick.get('roundId') + round_pick = pick.get('roundPickNumber') + bid_amount = pick.get('bidAmount') + keeper_status = pick.get('keeper') + nominatingTeam = self.get_team_data(pick.get('nominatingTeamId')) + self.draft.append(BasePick(team, playerId, playerName, round_num, round_pick, bid_amount, keeper_status, nominatingTeam)) + def _fetch_teams(self, data, TeamClass, pro_schedule = None): '''Fetch teams in league''' self.teams = [] @@ -102,3 +125,9 @@ def _get_all_pro_schedule(self): def standings(self) -> List: standings = sorted(self.teams, key=lambda x: x.final_standing if x.final_standing != 0 else x.standing, reverse=False) return standings + + def get_team_data(self, team_id: int) -> List: + for team in self.teams: + if team_id == team.team_id: + return team + return None diff --git a/espn_api/basketball/pick.py b/espn_api/base_pick.py similarity index 89% rename from espn_api/basketball/pick.py rename to espn_api/base_pick.py index 62109072..f75cb083 100644 --- a/espn_api/basketball/pick.py +++ b/espn_api/base_pick.py @@ -1,5 +1,5 @@ -class Pick(object): +class BasePick(object): ''' Pick represents a pick in draft ''' def __init__(self, team, playerId, playerName, round_num, round_pick, bid_amount, keeper_status, nominatingTeam): self.team = team @@ -15,4 +15,4 @@ def __repr__(self): return 'Pick(R:%s P:%s, %s, %s)' % (self.round_num, self.round_pick, self.playerName, self.team) def auction_repr(self): - return ', '.join(map(str, [self.team.owner, self.playerId, self.playerName, self.bid_amount, self.keeper_status])) + return ', '.join(map(str, [self.team.owner, self.playerId, self.playerName, self.bid_amount, self.keeper_status])) \ No newline at end of file diff --git a/espn_api/baseball/league.py b/espn_api/baseball/league.py index 58fdba1f..83571c82 100644 --- a/espn_api/baseball/league.py +++ b/espn_api/baseball/league.py @@ -39,6 +39,7 @@ def fetch_league(self): self.scoring_type = data['settings']['scoringSettings']['scoringType'] self._fetch_teams(data) self._box_score_class = self._set_scoring_class(self.scoring_type) + super()._fetch_draft() def _fetch_league(self): data = super()._fetch_league() @@ -84,12 +85,6 @@ def scoreboard(self, matchupPeriod: int = None) -> List[Matchup]: return matchups - def get_team_data(self, team_id: int) -> Team: - for team in self.teams: - if team_id == team.team_id: - return team - return None - def recent_activity(self, size: int = 25, msg_type: str = None, offset: int = 0) -> List[Activity]: '''Returns a list of recent league activities (Add, Drop, Trade)''' if self.year < 2019: diff --git a/espn_api/basketball/league.py b/espn_api/basketball/league.py index f4717318..59cacf13 100644 --- a/espn_api/basketball/league.py +++ b/espn_api/basketball/league.py @@ -5,7 +5,6 @@ from .team import Team from .player import Player from .matchup import Matchup -from .pick import Pick from .box_score import get_box_scoring_type_class, BoxScore from .constant import PRO_TEAM_MAP from .activity import Activity @@ -22,7 +21,7 @@ def __init__(self, league_id: int, year: int, espn_s2=None, swid=None, fetch_lea def fetch_league(self): data = self._fetch_league() self._fetch_teams(data) - self._fetch_draft() + super()._fetch_draft() self.BoxScoreClass = get_box_scoring_type_class(self.settings.scoring_type) @@ -60,28 +59,6 @@ def _fetch_teams(self, data): if matchup.home_team == opponent.team_id: matchup.home_team = opponent - 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['draftDetail']['drafted']: - return - - picks = data['draftDetail']['picks'] - for pick in picks: - team = self.get_team_data(pick['teamId']) - playerId = pick['playerId'] - playerName = '' - if playerId in self.player_map: - playerName = self.player_map[playerId] - round_num = pick['roundId'] - round_pick = pick['roundPickNumber'] - bid_amount = pick['bidAmount'] - keeper_status = pick['keeper'] - nominatingTeam = self.get_team_data(pick['nominatingTeamId']) - self.draft.append(Pick(team, playerId, playerName, round_num, round_pick, bid_amount, keeper_status, nominatingTeam)) - def standings(self) -> List[Team]: standings = sorted(self.teams, key=lambda x: x.final_standing if x.final_standing != 0 else x.standing, reverse=False) return standings @@ -107,12 +84,6 @@ def scoreboard(self, matchupPeriod: int = None) -> List[Matchup]: return matchups - def get_team_data(self, team_id: int) -> Team: - for team in self.teams: - if team_id == team.team_id: - return team - return None - def recent_activity(self, size: int = 25, msg_type: str = None, offset: int = 0) -> List[Activity]: '''Returns a list of recent league activities (Add, Drop, Trade)''' if self.year < 2019: diff --git a/espn_api/football/league.py b/espn_api/football/league.py index 96f9deb1..8a823856 100644 --- a/espn_api/football/league.py +++ b/espn_api/football/league.py @@ -5,7 +5,6 @@ from ..base_league import BaseLeague from .team import Team from .matchup import Matchup -from .pick import Pick from .box_score import BoxScore from .box_player import BoxPlayer from .player import Player @@ -41,7 +40,7 @@ def _fetch_league(self): self.nfl_week = data['status']['latestScoringPeriod'] self._fetch_players() self._fetch_teams(data) - self._fetch_draft() + super()._fetch_draft() def _fetch_teams(self, data): '''Fetch teams in league''' @@ -61,28 +60,6 @@ def _fetch_teams(self, data): mov = team.scores[week] - opponent.scores[week] team.mov.append(mov) - 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['draftDetail']['drafted']: - return - - picks = data['draftDetail']['picks'] - for pick in picks: - team = self.get_team_data(pick['teamId']) - playerId = pick['playerId'] - playerName = '' - if playerId in self.player_map: - playerName = self.player_map[playerId] - round_num = pick['roundId'] - round_pick = pick['roundPickNumber'] - bid_amount = pick['bidAmount'] - keeper_status = pick['keeper'] - nominatingTeam = self.get_team_data(pick['nominatingTeamId']) - self.draft.append(Pick(team, playerId, playerName, round_num, round_pick, bid_amount, keeper_status, nominatingTeam)) - def _get_positional_ratings(self, week: int): params = { 'view': 'mPositionalRatings', @@ -249,11 +226,6 @@ def least_scored_week(self) -> Tuple[Team, int]: least_tup = sorted(least_scored_tup, key=lambda tup: int(tup[1]), reverse=False) return least_tup[0] - def get_team_data(self, team_id: int) -> Team: - for team in self.teams: - if team_id == team.team_id: - return team - return None def recent_activity(self, size: int = 25, msg_type: str = None, offset: int = 0) -> List[Activity]: '''Returns a list of recent league activities (Add, Drop, Trade)''' diff --git a/espn_api/football/pick.py b/espn_api/football/pick.py deleted file mode 100644 index 10893259..00000000 --- a/espn_api/football/pick.py +++ /dev/null @@ -1,18 +0,0 @@ - -class Pick(object): - ''' Pick represents a pick in draft ''' - def __init__(self, team, playerId, playerName, round_num, round_pick, bid_amount, keeper_status, nominatingTeam): - self.team = team - self.playerId = playerId - self.playerName = playerName - self.round_num = round_num - self.round_pick = round_pick - self.bid_amount = bid_amount - self.keeper_status = keeper_status - self.nominatingTeam = nominatingTeam - - def __repr__(self): - return 'Pick(%s, %s)' % (self.playerName, self.team) - - def auction_repr(self): - return ', '.join(map(str, [self.team, self.playerId, self.playerName, self.bid_amount, self.keeper_status])) diff --git a/espn_api/hockey/league.py b/espn_api/hockey/league.py index 84e2b10f..ed13df65 100644 --- a/espn_api/hockey/league.py +++ b/espn_api/hockey/league.py @@ -23,6 +23,7 @@ def __init__(self, league_id: int, year: int, espn_s2=None, swid=None, fetch_lea def fetch_league(self): data = self._fetch_league() self._fetch_teams(data) + super()._fetch_draft() def _fetch_league(self): data = super()._fetch_league() @@ -84,11 +85,6 @@ def scoreboard(self, matchupPeriod: int = None) -> List[Matchup]: return matchups - def get_team_data(self, team_id: int) -> Team: - for team in self.teams: - if team_id == team.team_id: - return team - return None def recent_activity(self, size: int = 25, msg_type: str = None, offset: int = 0) -> List[Activity]: '''Returns a list of recent league activities (Add, Drop, Trade)''' diff --git a/espn_api/wbasketball/league.py b/espn_api/wbasketball/league.py index e5ab5202..c4893c7c 100644 --- a/espn_api/wbasketball/league.py +++ b/espn_api/wbasketball/league.py @@ -24,6 +24,7 @@ def __init__(self, league_id: int, year: int, espn_s2=None, swid=None, fetch_lea def fetch_league(self): data = self._fetch_league() self._fetch_teams(data) + super()._fetch_draft() def _fetch_league(self): data = super()._fetch_league() @@ -84,11 +85,6 @@ def scoreboard(self, matchupPeriod: int = None) -> List[Matchup]: return matchups - def get_team_data(self, team_id: int) -> Team: - for team in self.teams: - if team_id == team.team_id: - return team - return None def recent_activity(self, size: int = 25, msg_type: str = None, offset: int = 0) -> List[Activity]: '''Returns a list of recent league activities (Add, Drop, Trade)''' From 51e3a0c56c40949f76d698d23d303b6aeac0144c Mon Sep 17 00:00:00 2001 From: Christian Wendt Date: Thu, 22 Feb 2024 17:33:35 +0000 Subject: [PATCH 2/4] update export --- espn_api/football/__init__.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/espn_api/football/__init__.py b/espn_api/football/__init__.py index 1aecf8ec..dfb16ff3 100644 --- a/espn_api/football/__init__.py +++ b/espn_api/football/__init__.py @@ -2,7 +2,6 @@ 'Team', 'Matchup', 'Player', - 'Pick', 'BoxPlayer' ] @@ -10,5 +9,4 @@ from .team import Team from .matchup import Matchup from .player import Player -from .pick import Pick from .box_player import BoxPlayer \ No newline at end of file From db66d5feed643ae9adc0f16c241945b031a10fda Mon Sep 17 00:00:00 2001 From: Christian Wendt Date: Fri, 23 Feb 2024 17:01:40 +0000 Subject: [PATCH 3/4] fix tests --- espn_api/base_pick.py | 2 +- tests/football/unit/test_league.py | 2 +- tests/football/unit/test_past_league.py | 2 +- tests/hockey/unit/test_league.py | 30 ++++++++++++++++++------- 4 files changed, 25 insertions(+), 11 deletions(-) diff --git a/espn_api/base_pick.py b/espn_api/base_pick.py index f75cb083..11cc04d0 100644 --- a/espn_api/base_pick.py +++ b/espn_api/base_pick.py @@ -15,4 +15,4 @@ def __repr__(self): return 'Pick(R:%s P:%s, %s, %s)' % (self.round_num, self.round_pick, self.playerName, self.team) def auction_repr(self): - return ', '.join(map(str, [self.team.owner, self.playerId, self.playerName, self.bid_amount, self.keeper_status])) \ No newline at end of file + return ', '.join(map(str, [self.team, self.playerId, self.playerName, self.bid_amount, self.keeper_status])) \ No newline at end of file diff --git a/tests/football/unit/test_league.py b/tests/football/unit/test_league.py index e4b589d7..6b6a606a 100644 --- a/tests/football/unit/test_league.py +++ b/tests/football/unit/test_league.py @@ -403,7 +403,7 @@ def test_draft(self, m): first_pick = league.draft[0] third_pick = league.draft[2] - self.assertEqual(repr(first_pick), 'Pick(Le\'Veon Bell, Team(Rollin\' With Mahomies))') + self.assertEqual(repr(first_pick), 'Pick(R:1 P:1, Le\'Veon Bell, Team(Rollin\' With Mahomies))') self.assertEqual(third_pick.round_num, 1) self.assertEqual(third_pick.round_pick, 3) self.assertEqual(third_pick.auction_repr(), 'Team(Goin\' HAM Newton), 13934, Antonio Brown, 0, False') diff --git a/tests/football/unit/test_past_league.py b/tests/football/unit/test_past_league.py index a1fc9b42..5c632209 100644 --- a/tests/football/unit/test_past_league.py +++ b/tests/football/unit/test_past_league.py @@ -57,7 +57,7 @@ def test_draft(self, m): first_pick = league.draft[0] third_pick = league.draft[2] - self.assertEqual(repr(first_pick), 'Pick(Eddie Lacy, Team(Show Me Your TD\'s))') + self.assertEqual(repr(first_pick), 'Pick(R:1 P:1, Eddie Lacy, Team(Show Me Your TD\'s))') self.assertEqual(third_pick.round_num, 1) self.assertEqual(third_pick.round_pick, 3) diff --git a/tests/hockey/unit/test_league.py b/tests/hockey/unit/test_league.py index 21298e2d..5677d3be 100644 --- a/tests/hockey/unit/test_league.py +++ b/tests/hockey/unit/test_league.py @@ -79,9 +79,11 @@ class HockeyLeagueTest(BaseLeagueTest): def setUp(self): super().setUp() + @mock.patch.object(EspnFantasyRequests, 'get_league_draft') @mock.patch.object(EspnFantasyRequests, 'get_league') - def test_league(self, mock_league_request): + def test_league(self, mock_league_request, mock_league_draft): mock_league_request.return_value = self.league_data + mock_league_draft.return_value = {} league = HockeyLeague(self.league_id, self.season) self.assertEqual(league.scoringPeriodId, 265) @@ -90,8 +92,10 @@ def test_league(self, mock_league_request): self.assertEqual(league.year, self.season) mock_league_request.assert_called_once() + @mock.patch.object(EspnFantasyRequests, 'get_league_draft') @mock.patch.object(EspnFantasyRequests, 'get_league') - def test_league_teams(self, mock_league_request): + def test_league_teams(self, mock_league_request, mock_league_draft): + mock_league_draft.return_value = {} mock_league_request.return_value = self.league_data expected_teams = set(["Team(Barkko Ruutu)", "Team(2 Minutes for.. Rooping?)", @@ -109,13 +113,15 @@ def test_league_teams(self, mock_league_request): for actual_team in actual_teams: self.assertIn(repr(actual_team), expected_teams) - mock_league_request.assert_called_once()\ + mock_league_request.assert_called_once() + @mock.patch.object(EspnFantasyRequests, 'get_league_draft') @mock.patch.object(EspnFantasyRequests, 'league_get') @mock.patch.object(EspnFantasyRequests, 'get_league') - def test_league_scoreboard(self, mock_get_league_request, mock_league_get_request): + def test_league_scoreboard(self, mock_get_league_request, mock_league_get_request, mock_league_draft): with open('tests/hockey/unit/data/matchup_data.json') as file: matchup_data = json.loads(file.read()) + mock_league_draft.return_value = {} mock_get_league_request.return_value = self.league_data mock_league_get_request.return_value = matchup_data league = HockeyLeague(self.league_id, self.season) @@ -129,8 +135,10 @@ def test_league_scoreboard(self, mock_get_league_request, mock_league_get_reques mock_get_league_request.assert_called_once() mock_league_get_request.assert_called_once() + @mock.patch.object(EspnFantasyRequests, 'get_league_draft') @mock.patch.object(EspnFantasyRequests, 'get_league') - def test_league_get_team_data(self, mock_get_league_request): + def test_league_get_team_data(self, mock_get_league_request, mock_league_draft): + mock_league_draft.return_value = {} mock_get_league_request.return_value = self.league_data league = HockeyLeague(self.league_id, self.season) @@ -141,11 +149,13 @@ def test_league_get_team_data(self, mock_get_league_request): mock_get_league_request.assert_called_once() + @mock.patch.object(EspnFantasyRequests, 'get_league_draft') @mock.patch.object(EspnFantasyRequests, 'league_get') @mock.patch.object(EspnFantasyRequests, 'get_league') - def test_league_free_agency(self, mock_get_league_request, mock_league_get_request): + def test_league_free_agency(self, mock_get_league_request, mock_league_get_request, mock_league_draft): with open('tests/hockey/unit/data/free_agent_data.json') as file: free_agents_data = json.loads(file.read()) + mock_league_draft.return_value = {} mock_get_league_request.return_value = self.league_data mock_league_get_request.return_value = free_agents_data league = HockeyLeague(self.league_id, self.season) @@ -159,11 +169,13 @@ def test_league_free_agency(self, mock_get_league_request, mock_league_get_reque mock_get_league_request.assert_called_once() mock_league_get_request.assert_called_once() + @mock.patch.object(EspnFantasyRequests, 'get_league_draft') @mock.patch.object(EspnFantasyRequests, 'league_get') @mock.patch.object(EspnFantasyRequests, 'get_league') - def test_league_recent_activity(self, mock_get_league_request, mock_league_get_request): + def test_league_recent_activity(self, mock_get_league_request, mock_league_get_request, mock_league_draft): with open('tests/hockey/unit/data/recent_activity_data.json') as file: activity_data = json.loads(file.read()) + mock_league_draft.return_value = {} mock_get_league_request.return_value = self.league_data mock_league_get_request.return_value = activity_data league = HockeyLeague(self.league_id, self.season) @@ -177,9 +189,11 @@ def test_league_recent_activity(self, mock_get_league_request, mock_league_get_r mock_get_league_request.assert_called_once() mock_league_get_request.assert_called_once() + @mock.patch.object(EspnFantasyRequests, 'get_league_draft') @mock.patch.object(EspnFantasyRequests, 'league_get') @mock.patch.object(EspnFantasyRequests, 'get_league') - def test_league_box_scores(self, mock_get_league_request, mock_league_get_request): + def test_league_box_scores(self, mock_get_league_request, mock_league_get_request, mock_league_draft): + mock_league_draft.return_value = {} with open('tests/hockey/unit/data/box_score_data.json') as file: box_score_data = json.loads(file.read()) mock_get_league_request.return_value = self.league_data From 1172ccc2ff920a8380089ac67962bca61f0a27bf Mon Sep 17 00:00:00 2001 From: Christian Wendt Date: Fri, 23 Feb 2024 17:18:50 +0000 Subject: [PATCH 4/4] in init call fetch league --- espn_api/baseball/league.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/espn_api/baseball/league.py b/espn_api/baseball/league.py index 83571c82..d61f2538 100644 --- a/espn_api/baseball/league.py +++ b/espn_api/baseball/league.py @@ -27,10 +27,7 @@ def __init__(self, league_id: int, year: int, espn_s2=None, swid=None, fetch_lea self._box_score_class = None if fetch_league: - data = self._fetch_league() - self.scoring_type = data['settings']['scoringSettings']['scoringType'] - self._fetch_teams(data) - + self.fetch_league() if self._box_score_class is None: self._box_score_class = self._set_scoring_class(self.scoring_type)