From 5a1306f09321614ea2d15baf1248b3be8c832873 Mon Sep 17 00:00:00 2001 From: Christian Date: Fri, 4 Sep 2020 15:13:17 -0700 Subject: [PATCH 1/4] New interface player_info --- espn_api/base_league.py | 2 ++ espn_api/football/box_player.py | 18 +++++++----------- espn_api/football/league.py | 20 +++++++++++++++++--- espn_api/football/player.py | 15 ++++++++++++++- 4 files changed, 40 insertions(+), 15 deletions(-) diff --git a/espn_api/base_league.py b/espn_api/base_league.py index 9cade5bc..9cebb842 100644 --- a/espn_api/base_league.py +++ b/espn_api/base_league.py @@ -69,7 +69,9 @@ def _fetch_players(self): data = self.espn_request.get_pro_players() # Map all player id's to player name for player in data: + # two way map to find playerId's by name self.player_map[player['id']] = player['fullName'] + self.player_map[player['fullName']] = player['id'] def _get_pro_schedule(self, scoringPeriodId: int = None): data = self.espn_request.get_pro_schedule() diff --git a/espn_api/football/box_player.py b/espn_api/football/box_player.py index e637c999..3ba34181 100644 --- a/espn_api/football/box_player.py +++ b/espn_api/football/box_player.py @@ -25,17 +25,13 @@ def __init__(self, data, pro_schedule, positional_rankings, week): self.pro_opponent = PRO_TEAM_MAP[opp_id] self.pro_pos_rank = positional_rankings[posId][str(opp_id)] if str(opp_id) in positional_rankings[posId] else 0 - - player_stats = player.get('stats') - for stats in player_stats: - stats_breakdown = stats.get('appliedStats') if stats.get('appliedStats') else stats.get('stats', {}) - points = round(stats.get('appliedTotal', 0), 2) - if stats.get('statSourceId') == 0 and stats.get('scoringPeriodId') == week: - self.points = points - self.points_breakdown = {PLAYER_STATS_MAP.get(int(k), k):v for (k,v) in stats_breakdown.items()} - elif stats.get('statSourceId') == 1 and stats.get('scoringPeriodId') == week: - self.projected_points = points - self.projected_breakdown = {PLAYER_STATS_MAP.get(int(k), k):v for (k,v) in stats_breakdown.items()} + stats = self.stats.get(week) + if stats and stats.get('stat_source') == 0: + self.points = stats.get('points') + self.points_breakdown = stats.get('breakdown') + elif stats and stats.get('stat_source') == 1: + self.projected_points = stats.get('points') + self.projected_breakdown = stats.get('breakdown') diff --git a/espn_api/football/league.py b/espn_api/football/league.py index 47b592e2..32eae5b5 100644 --- a/espn_api/football/league.py +++ b/espn_api/football/league.py @@ -149,12 +149,10 @@ def recent_activity(self, size: int = 25, msg_type: str = None) -> List[Activity 'view': 'kona_league_communication' } - filters = {"topics":{"filterType":{"value":["ACTIVITY_TRANSACTIONS"]},"limit":size,"limitPerMessageSet":{"value":25},"offset":0,"sortMessageDate":{"sortPriority":1,"sortAsc":False},"sortFor":{"sortPriority":2,"sortAsc":False},"filterDateRange":{"value":1564689600000,"additionalValue":1583110842000},"filterIncludeMessageTypeIds":{"value":msg_types}}} + filters = {"topics":{"filterType":{"value":["ACTIVITY_TRANSACTIONS"]},"limit":size,"limitPerMessageSet":{"value":25},"offset":0,"sortMessageDate":{"sortPriority":1,"sortAsc":False},"sortFor":{"sortPriority":2,"sortAsc":False},"filterIncludeMessageTypeIds":{"value":msg_types}}} headers = {'x-fantasy-filter': json.dumps(filters)} data = self.espn_request.league_get(extend='/communication/', params=params, headers=headers) - data = data['topics'] - activity = [Activity(topic, self.player_map, self.get_team_data) for topic in data] return activity @@ -259,3 +257,19 @@ def free_agents(self, week: int=None, size: int=50, position: str=None) -> List[ positional_rankings = self._get_positional_ratings(week) return [BoxPlayer(player, pro_schedule, positional_rankings, week) for player in players] + + def player_info(self, name: str): + ''' Returns Player class if name found ''' + playerId = self.player_map.get(name) + + if playerId is None: + return None + params = { 'view': 'kona_playercard' } + filters = {'players':{'filterIds':{'value':[playerId]}}} + headers = {'x-fantasy-filter': json.dumps(filters)} + + data = self.espn_request.league_get(params=params, headers=headers) + + player = data['players'][0] + return Player(player) + diff --git a/espn_api/football/player.py b/espn_api/football/player.py index da11dff5..e560c066 100644 --- a/espn_api/football/player.py +++ b/espn_api/football/player.py @@ -1,4 +1,4 @@ -from .constant import POSITION_MAP, PRO_TEAM_MAP +from .constant import POSITION_MAP, PRO_TEAM_MAP, PLAYER_STATS_MAP from .utils import json_parsing class Player(object): @@ -10,12 +10,25 @@ def __init__(self, data): self.eligibleSlots = [POSITION_MAP[pos] for pos in json_parsing(data, 'eligibleSlots')] self.acquisitionType = json_parsing(data, 'acquisitionType') self.proTeam = PRO_TEAM_MAP[json_parsing(data, 'proTeamId')] + self.stats = {} # Get players main position for pos in json_parsing(data, 'eligibleSlots'): if (pos != 25 and '/' not in POSITION_MAP[pos]) or '/' in self.name: self.position = POSITION_MAP[pos] break + + # set each scoring period statsd + player = data['playerPoolEntry']['player'] if 'playerPoolEntry' in data else data['player'] + player_stats = player.get('stats') + for stats in player_stats: + stats_breakdown = stats.get('appliedStats') if stats.get('appliedStats') else stats.get('stats', {}) + breakdown = {PLAYER_STATS_MAP.get(int(k), k):v for (k,v) in stats_breakdown.items()} + points = round(stats.get('appliedTotal', 0), 2) + scoring_period = stats.get('scoringPeriodId') + stat_source = stats.get('statSourceId') + self.stats[scoring_period] = {'breakdown': breakdown, 'points': points, 'stat_source': stat_source} + def __repr__(self): return 'Player(%s)' % (self.name, ) From f813622f60296d40e675cfb183b66af9e988213e Mon Sep 17 00:00:00 2001 From: Christian Date: Fri, 4 Sep 2020 16:03:43 -0700 Subject: [PATCH 2/4] Keep projected and regular points --- espn_api/football/box_player.py | 12 ++++-------- espn_api/football/league.py | 2 ++ espn_api/football/player.py | 7 ++++++- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/espn_api/football/box_player.py b/espn_api/football/box_player.py index 3ba34181..798c8247 100644 --- a/espn_api/football/box_player.py +++ b/espn_api/football/box_player.py @@ -7,8 +7,6 @@ class BoxPlayer(Player): def __init__(self, data, pro_schedule, positional_rankings, week): super(BoxPlayer, self).__init__(data) self.slot_position = 'FA' - self.points = 0 - self.projected_points = 0 self.pro_opponent = "None" # professional team playing against self.pro_pos_rank = 0 # rank of professional team against player position self.game_played = 100 # 0-100 for percent of game played @@ -26,12 +24,10 @@ def __init__(self, data, pro_schedule, positional_rankings, week): self.pro_pos_rank = positional_rankings[posId][str(opp_id)] if str(opp_id) in positional_rankings[posId] else 0 stats = self.stats.get(week) - if stats and stats.get('stat_source') == 0: - self.points = stats.get('points') - self.points_breakdown = stats.get('breakdown') - elif stats and stats.get('stat_source') == 1: - self.projected_points = stats.get('points') - self.projected_breakdown = stats.get('breakdown') + self.points = stats.get('points', 0) + self.points_breakdown = stats.get('breakdown', 0) + self.projected_points = stats.get('projected_points', 0) + self.projected_breakdown = stats.get('projected_breakdown', 0) diff --git a/espn_api/football/league.py b/espn_api/football/league.py index 32eae5b5..ef042266 100644 --- a/espn_api/football/league.py +++ b/espn_api/football/league.py @@ -265,6 +265,8 @@ def player_info(self, name: str): if playerId is None: return None params = { 'view': 'kona_playercard' } + # need to get final scoring period for league and add to filte + # example {"players":{"filterIds":{"value":[5536]},"filterStatsForTopScoringPeriodIds":{"value":16}}} filters = {'players':{'filterIds':{'value':[playerId]}}} headers = {'x-fantasy-filter': json.dumps(filters)} diff --git a/espn_api/football/player.py b/espn_api/football/player.py index e560c066..0a876a56 100644 --- a/espn_api/football/player.py +++ b/espn_api/football/player.py @@ -27,7 +27,12 @@ def __init__(self, data): points = round(stats.get('appliedTotal', 0), 2) scoring_period = stats.get('scoringPeriodId') stat_source = stats.get('statSourceId') - self.stats[scoring_period] = {'breakdown': breakdown, 'points': points, 'stat_source': stat_source} + (points_type, breakdown_type) = ('points', 'breakdown') if stat_source == 0 else ('projected_points', 'projected_breakdown') + if self.stats.get(scoring_period): + self.stats[scoring_period][points_type] = points + self.stats[scoring_period][breakdown_type] = breakdown + else: + self.stats[scoring_period] = {points_type: points, breakdown_type: breakdown} def __repr__(self): return 'Player(%s)' % (self.name, ) From 96b91c5af9df2f966090258cafbc01dd92de9f26 Mon Sep 17 00:00:00 2001 From: Christian Date: Sat, 5 Sep 2020 11:27:42 -0700 Subject: [PATCH 3/4] Add unit tests --- espn_api/football/league.py | 4 +- .../unit/data/league_2019_playerCard.json | 947 ++++++++++++++++++ tests/football/unit/test_league.py | 17 + 3 files changed, 965 insertions(+), 3 deletions(-) create mode 100644 tests/football/unit/data/league_2019_playerCard.json diff --git a/espn_api/football/league.py b/espn_api/football/league.py index ef042266..6203ffc8 100644 --- a/espn_api/football/league.py +++ b/espn_api/football/league.py @@ -265,9 +265,7 @@ def player_info(self, name: str): if playerId is None: return None params = { 'view': 'kona_playercard' } - # need to get final scoring period for league and add to filte - # example {"players":{"filterIds":{"value":[5536]},"filterStatsForTopScoringPeriodIds":{"value":16}}} - filters = {'players':{'filterIds':{'value':[playerId]}}} + filters = {'players':{'filterIds':{'value':[playerId]}, 'filterStatsForTopScoringPeriodIds':{'value':16}}} headers = {'x-fantasy-filter': json.dumps(filters)} data = self.espn_request.league_get(params=params, headers=headers) diff --git a/tests/football/unit/data/league_2019_playerCard.json b/tests/football/unit/data/league_2019_playerCard.json new file mode 100644 index 00000000..500f85f0 --- /dev/null +++ b/tests/football/unit/data/league_2019_playerCard.json @@ -0,0 +1,947 @@ +{ + "players": [ + { + "appliedStatTotal": 145.5, + "draftAuctionValue": 0, + "id": 3045147, + "keeperValue": 0, + "keeperValueFuture": 5, + "lineupLocked": false, + "onTeamId": 4, + "player": { + "active": true, + "defaultPositionId": 2, + "draftRanksByRankType": { + "STANDARD": { + "auctionValue": 17, + "rank": 47, + "rankSourceId": 0, + "rankType": "STANDARD", + "slotId": 0 + }, + "PPR": { + "auctionValue": 17, + "rank": 47, + "rankSourceId": 0, + "rankType": "PPR", + "slotId": 0 + } + }, + "droppable": true, + "eligibleSlots": [ + 2, + 3, + 23, + 7, + 20, + 21 + ], + "firstName": "James", + "fullName": "James Conner", + "id": 3045147, + "injured": false, + "injuryStatus": "ACTIVE", + "invalid": false, + "jersey": "30", + "lastName": "Conner", + "lastNewsDate": 1598290605000, + "lastVideoDate": 1596954578000, + "laterality": "NONE", + "ownership": { + "auctionValueAverage": 19.938341695273305, + "auctionValueAverageChange": 3.8592952711829653, + "averageDraftPosition": 49.15868710096434, + "averageDraftPositionPercentChange": 6.982647190567576, + "percentChange": 1.6136190536393684, + "percentOwned": 96.73380115206605, + "percentStarted": 73.87311457396864 + }, + "proTeamId": 23, + "rankings": { + "0": [ + { + "auctionValue": 0, + "rank": 19, + "rankSourceId": 7, + "rankType": "STANDARD", + "slotId": 2 + }, + { + "auctionValue": 0, + "rank": 0, + "rankSourceId": 0, + "rankType": "PPR", + "slotId": 23 + }, + { + "auctionValue": 0, + "rank": 19, + "rankSourceId": 7, + "rankType": "PPR", + "slotId": 2 + }, + { + "auctionValue": 0, + "rank": 18, + "rankSourceId": 5, + "rankType": "STANDARD", + "slotId": 2 + }, + { + "auctionValue": 0, + "rank": 17, + "rankSourceId": 6, + "rankType": "PPR", + "slotId": 2 + }, + { + "auctionValue": 0, + "rank": 20, + "rankSourceId": 10, + "rankType": "PPR", + "slotId": 2 + }, + { + "auctionValue": 0, + "rank": 19, + "rankSourceId": 5, + "rankType": "PPR", + "slotId": 2 + }, + { + "auctionValue": 0, + "rank": 21, + "rankSourceId": 3, + "rankType": "STANDARD", + "slotId": 2 + }, + { + "auctionValue": 0, + "rank": 21, + "rankSourceId": 3, + "rankType": "PPR", + "slotId": 2 + }, + { + "auctionValue": 0, + "rank": 19, + "rankSourceId": 2, + "rankType": "PPR", + "slotId": 2 + }, + { + "auctionValue": 0, + "rank": 21, + "rankSourceId": 7, + "rankType": "PPR", + "slotId": 23 + }, + { + "auctionValue": 0, + "rank": 0, + "rankSourceId": 0, + "rankType": "STANDARD", + "slotId": 2 + }, + { + "auctionValue": 0, + "rank": 0, + "rankSourceId": 0, + "rankType": "PPR", + "slotId": 2 + }, + { + "auctionValue": 0, + "rank": 19, + "rankSourceId": 9, + "rankType": "STANDARD", + "slotId": 2 + }, + { + "auctionValue": 0, + "rank": 63, + "rankSourceId": 10, + "rankType": "PPR", + "slotId": 23 + } + ] + }, + "seasonOutlook": "Conner returns as the lead back in Pittsburgh, but durability has become a significant concern for a player who has missed at least two games in each of his three NFL seasons. Despite missing three games in 2018, Conner broke out with 1,462 yards and 13 TDs on 269 touches en route to finishing sixth among running backs in fantasy points. He sat ninth at the position through Week 8 last season, but injuries limited him to 54 snaps the rest of the season. A return to full health by Conner and Ben Roethlisberger very well could lead to a bounce-back campaign for the 25-year-old, though he'll need to fend off Benny Snell Jr., Jaylen Samuels and rookie Anthony McFarland Jr. for touches. Consider Conner a flex option.", + "stance": "NONE", + "stats": [ + { + "appliedStats": {}, + "appliedTotal": 0.0, + "externalId": "401127950", + "id": "01401127950", + "proTeamId": 23, + "scoringPeriodId": 17, + "seasonId": 2019, + "statSourceId": 0, + "statSplitTypeId": 1, + "stats": {}, + "variance": {} + }, + { + "appliedStats": { + "24": 3.2 + }, + "appliedTotal": 3.2, + "externalId": "401127933", + "id": "01401127933", + "proTeamId": 23, + "scoringPeriodId": 16, + "seasonId": 2019, + "statSourceId": 0, + "statSplitTypeId": 1, + "stats": { + "23": 6.0, + "24": 32.0, + "27": 6.0, + "28": 3.0, + "29": 1.0, + "30": 1.0, + "33": 1.0, + "39": 5.333, + "40": 32.0, + "156": 1.0, + "210": 1.0 + }, + "variance": {} + }, + { + "appliedStats": { + "53": 4.0, + "24": 4.2, + "42": 0.9, + "43": 6.0 + }, + "appliedTotal": 15.1, + "externalId": "401128065", + "id": "01401128065", + "proTeamId": 23, + "scoringPeriodId": 15, + "seasonId": 2019, + "statSourceId": 0, + "statSplitTypeId": 1, + "stats": { + "23": 8.0, + "24": 42.0, + "27": 8.0, + "28": 4.0, + "29": 2.0, + "30": 1.0, + "33": 1.0, + "39": 5.25, + "40": 42.0, + "41": 4.0, + "42": 9.0, + "43": 1.0, + "47": 1.0, + "53": 4.0, + "58": 5.0, + "59": 21.0, + "60": 2.25, + "61": 9.0, + "156": 1.0, + "158": 6.0, + "184": 1.0, + "210": 1.0 + }, + "variance": {} + }, + { + "appliedStats": {}, + "appliedTotal": 0.0, + "externalId": "401128002", + "id": "01401128002", + "proTeamId": 23, + "scoringPeriodId": 14, + "seasonId": 2019, + "statSourceId": 0, + "statSplitTypeId": 1, + "stats": {}, + "variance": {} + }, + { + "appliedStats": {}, + "appliedTotal": 0.0, + "externalId": "401128107", + "id": "01401128107", + "proTeamId": 23, + "scoringPeriodId": 13, + "seasonId": 2019, + "statSourceId": 0, + "statSplitTypeId": 1, + "stats": {}, + "variance": {} + }, + { + "appliedStats": {}, + "appliedTotal": 0.0, + "externalId": "401127918", + "id": "01401127918", + "proTeamId": 23, + "scoringPeriodId": 12, + "seasonId": 2019, + "statSourceId": 0, + "statSplitTypeId": 1, + "stats": {}, + "variance": {} + }, + { + "appliedStats": { + "53": 1.0, + "24": 1.0, + "42": 0.6000000000000001 + }, + "appliedTotal": 2.6, + "externalId": "401128044", + "id": "01401128044", + "proTeamId": 23, + "scoringPeriodId": 11, + "seasonId": 2019, + "statSourceId": 0, + "statSplitTypeId": 1, + "stats": { + "23": 5.0, + "24": 10.0, + "27": 2.0, + "28": 1.0, + "33": 1.0, + "39": 2.0, + "40": 10.0, + "41": 1.0, + "42": 6.0, + "47": 1.0, + "53": 1.0, + "58": 2.0, + "59": 6.0, + "60": 6.0, + "61": 6.0, + "156": 1.0, + "210": 1.0 + }, + "variance": {} + }, + { + "appliedStats": {}, + "appliedTotal": 0.0, + "externalId": "401127989", + "id": "01401127989", + "proTeamId": 23, + "scoringPeriodId": 10, + "seasonId": 2019, + "statSourceId": 0, + "statSplitTypeId": 1, + "stats": {}, + "variance": {} + }, + { + "appliedStats": {}, + "appliedTotal": 0.0, + "externalId": "401128083", + "id": "01401128083", + "proTeamId": 23, + "scoringPeriodId": 9, + "seasonId": 2019, + "statSourceId": 0, + "statSplitTypeId": 1, + "stats": {}, + "variance": {} + }, + { + "appliedStats": { + "53": 3.0, + "24": 14.5, + "25": 6.0, + "42": 0.5 + }, + "appliedTotal": 24.0, + "externalId": "401128074", + "id": "01401128074", + "proTeamId": 23, + "scoringPeriodId": 8, + "seasonId": 2019, + "statSourceId": 0, + "statSplitTypeId": 1, + "stats": { + "23": 23.0, + "24": 145.0, + "25": 1.0, + "27": 29.0, + "28": 14.0, + "29": 7.0, + "30": 5.0, + "31": 2.0, + "32": 1.0, + "33": 4.0, + "34": 2.0, + "37": 1.0, + "39": 6.304, + "40": 145.0, + "41": 3.0, + "42": 5.0, + "47": 1.0, + "53": 3.0, + "58": 4.0, + "59": 12.0, + "60": 1.667, + "61": 5.0, + "155": 1.0, + "158": 6.0, + "179": 1.0, + "210": 1.0 + }, + "variance": {} + }, + { + "appliedStats": { + "53": 7.0, + "24": 4.1000000000000005, + "25": 6.0, + "42": 7.800000000000001, + "43": 6.0 + }, + "appliedTotal": 30.900000000000002, + "externalId": "401128131", + "id": "01401128131", + "proTeamId": 23, + "scoringPeriodId": 6, + "seasonId": 2019, + "statSourceId": 0, + "statSplitTypeId": 1, + "stats": { + "23": 16.0, + "24": 41.0, + "25": 1.0, + "27": 8.0, + "28": 4.0, + "29": 2.0, + "30": 1.0, + "33": 3.0, + "34": 1.0, + "39": 2.563, + "40": 41.0, + "41": 7.0, + "42": 78.0, + "43": 1.0, + "47": 15.0, + "48": 7.0, + "49": 3.0, + "50": 3.0, + "51": 1.0, + "53": 7.0, + "54": 1.0, + "58": 7.0, + "59": 88.0, + "60": 11.143, + "61": 78.0, + "155": 1.0, + "158": 12.0, + "180": 1.0, + "185": 1.0, + "210": 1.0 + }, + "variance": {} + }, + { + "appliedStats": { + "24": 5.5, + "25": 6.0 + }, + "appliedTotal": 11.5, + "externalId": "401128011", + "id": "01401128011", + "proTeamId": 23, + "scoringPeriodId": 5, + "seasonId": 2019, + "statSourceId": 0, + "statSplitTypeId": 1, + "stats": { + "23": 14.0, + "24": 55.0, + "25": 1.0, + "27": 11.0, + "28": 5.0, + "29": 2.0, + "30": 2.0, + "31": 1.0, + "33": 2.0, + "34": 1.0, + "39": 3.929, + "40": 55.0, + "156": 1.0, + "158": 6.0, + "179": 1.0, + "210": 1.0 + }, + "variance": {} + }, + { + "appliedStats": { + "53": 8.0, + "24": 4.2, + "42": 8.3, + "43": 6.0 + }, + "appliedTotal": 26.5, + "externalId": "401128109", + "id": "01401128109", + "proTeamId": 23, + "scoringPeriodId": 4, + "seasonId": 2019, + "statSourceId": 0, + "statSplitTypeId": 1, + "stats": { + "23": 10.0, + "24": 42.0, + "27": 8.0, + "28": 4.0, + "29": 2.0, + "30": 1.0, + "33": 2.0, + "34": 1.0, + "39": 4.2, + "40": 42.0, + "41": 8.0, + "42": 83.0, + "43": 1.0, + "47": 16.0, + "48": 8.0, + "49": 4.0, + "50": 3.0, + "51": 1.0, + "53": 8.0, + "54": 1.0, + "58": 8.0, + "59": 92.0, + "60": 10.375, + "61": 83.0, + "155": 1.0, + "158": 6.0, + "185": 1.0, + "210": 1.0 + }, + "variance": {} + }, + { + "appliedStats": { + "53": 4.0, + "72": -2.0, + "24": 4.3, + "42": 1.4000000000000001 + }, + "appliedTotal": 7.7, + "externalId": "401127998", + "id": "01401127998", + "proTeamId": 23, + "scoringPeriodId": 3, + "seasonId": 2019, + "statSourceId": 0, + "statSplitTypeId": 1, + "stats": { + "23": 13.0, + "24": 43.0, + "27": 8.0, + "28": 4.0, + "29": 2.0, + "30": 1.0, + "33": 2.0, + "34": 1.0, + "39": 3.308, + "40": 43.0, + "41": 4.0, + "42": 14.0, + "47": 2.0, + "48": 1.0, + "53": 4.0, + "58": 4.0, + "59": 19.0, + "60": 3.5, + "61": 14.0, + "66": 1.0, + "68": 1.0, + "70": 1.0, + "72": 1.0, + "73": 1.0, + "156": 1.0, + "210": 1.0 + }, + "variance": {} + }, + { + "appliedStats": { + "53": 3.0, + "24": 3.3000000000000003, + "25": 6.0, + "42": 1.2000000000000002 + }, + "appliedTotal": 13.5, + "externalId": "401128110", + "id": "01401128110", + "proTeamId": 23, + "scoringPeriodId": 2, + "seasonId": 2019, + "statSourceId": 0, + "statSplitTypeId": 1, + "stats": { + "23": 11.0, + "24": 33.0, + "25": 1.0, + "27": 6.0, + "28": 3.0, + "29": 1.0, + "30": 1.0, + "33": 2.0, + "34": 1.0, + "39": 3.0, + "40": 33.0, + "41": 3.0, + "42": 12.0, + "47": 2.0, + "48": 1.0, + "53": 3.0, + "58": 4.0, + "59": 19.0, + "60": 4.0, + "61": 12.0, + "156": 1.0, + "158": 6.0, + "179": 1.0, + "210": 1.0 + }, + "variance": {} + }, + { + "appliedStats": { + "53": 4.0, + "24": 2.1, + "42": 4.4 + }, + "appliedTotal": 10.5, + "externalId": "401127860", + "id": "01401127860", + "proTeamId": 23, + "scoringPeriodId": 1, + "seasonId": 2019, + "statSourceId": 0, + "statSplitTypeId": 1, + "stats": { + "23": 10.0, + "24": 21.0, + "27": 4.0, + "28": 2.0, + "29": 1.0, + "33": 2.0, + "34": 1.0, + "39": 2.1, + "40": 21.0, + "41": 4.0, + "42": 44.0, + "47": 8.0, + "48": 4.0, + "49": 2.0, + "50": 1.0, + "53": 4.0, + "58": 4.0, + "59": 41.0, + "60": 11.0, + "61": 44.0, + "156": 1.0, + "210": 1.0 + }, + "variance": {} + }, + { + "appliedAverage": 14.841142385692308, + "appliedStats": { + "53": 37.6698422, + "72": -1.955378828, + "24": 80.53395337, + "25": 38.29912836, + "26": 0.546, + "42": 29.23931975, + "43": 8.412920922000001, + "44": 0.13488524, + "63": 0.05418 + }, + "appliedTotal": 192.934851014, + "externalId": "2020", + "id": "102020", + "proTeamId": 0, + "scoringPeriodId": 0, + "seasonId": 2020, + "statSourceId": 1, + "statSplitTypeId": 0, + "stats": { + "23": 190.9557123, + "24": 805.3395337, + "25": 6.38318806, + "26": 0.273, + "27": 161.0, + "28": 80.0, + "29": 40.0, + "30": 32.0, + "31": 16.0, + "33": 38.0, + "34": 19.0, + "35": 0.389, + "36": 0.272, + "37": 1.79, + "38": 0.0612, + "39": 4.217415253, + "40": 61.06840066, + "42": 292.3931975, + "43": 1.402153487, + "44": 0.06744262, + "45": 0.05837297, + "46": 0.038146736, + "47": 58.0, + "48": 29.0, + "49": 14.0, + "50": 11.0, + "51": 5.0, + "53": 37.6698422, + "54": 7.0, + "55": 3.0, + "56": 0.128602051, + "57": 0.00398, + "58": 47.36084466, + "60": 7.761996877, + "61": 22.17199602, + "62": 0.339961209, + "63": 0.00903, + "66": 1.713827744, + "67": 0.338086878, + "68": 2.051914623, + "70": 0.788, + "71": 0.189328652, + "72": 0.977689414, + "73": 0.977689414, + "210": 13.1875 + }, + "variance": { + "23": 37.51639021, + "24": 246.4655802, + "25": 4.782562034, + "26": 0.98345237, + "35": 0.751763803, + "36": 0.636107833, + "42": 153.0561732, + "43": 2.282881238, + "44": 1.508552663, + "45": 0.520451863, + "46": 0.462623879, + "53": 11.8377659, + "58": 14.10601822, + "63": 0.005782798, + "68": 2.480427476, + "72": 2.031208468 + } + }, + { + "appliedStats": { + "53": 3.140520657, + "72": -0.163930348, + "24": 6.748422759, + "25": 3.3088462739999995, + "26": 0.047999184, + "42": 2.615391547, + "43": 0.8006209440000001, + "44": 0.012608172, + "63": 0.0045423239999999995 + }, + "appliedTotal": 16.515021513000004, + "externalId": "20201", + "id": "1120201", + "proTeamId": 0, + "scoringPeriodId": 1, + "seasonId": 2020, + "statSourceId": 1, + "statSplitTypeId": 1, + "stats": { + "23": 16.03025454, + "24": 67.48422759, + "25": 0.551474379, + "26": 0.023999592, + "27": 13.0, + "28": 6.0, + "29": 3.0, + "30": 2.0, + "31": 1.0, + "33": 3.0, + "34": 1.0, + "35": 0.033756699, + "36": 0.023629689, + "37": 0.199280453, + "38": 0.0068, + "39": 4.209803868, + "40": 67.48422759, + "42": 26.15391547, + "43": 0.133436824, + "44": 0.006304086, + "45": 0.004864677, + "46": 0.003179067, + "47": 5.0, + "48": 2.0, + "49": 1.0, + "50": 1.0, + "53": 3.140520657, + "56": 0.016783685, + "57": 5.19083E-4, + "58": 3.948036673, + "60": 8.32789156, + "61": 26.15391547, + "62": 0.030303678, + "63": 7.57054E-4, + "66": 0.143871554, + "67": 0.028186177, + "68": 0.17205773, + "70": 0.066180915, + "71": 0.015784259, + "72": 0.081965174, + "73": 0.081965174, + "210": 1.0 + }, + "variance": { + "23": 6.487583879, + "24": 42.62046843, + "25": 0.827032456, + "26": 0.170065129, + "35": 0.13, + "36": 0.11, + "42": 26.46749211, + "43": 0.394771017, + "44": 0.260868966, + "45": 0.09, + "46": 0.08, + "53": 2.047065263, + "58": 2.439306551, + "63": 0.001, + "68": 0.428932027, + "72": 0.351250087 + } + }, + { + "appliedAverage": 0.0, + "appliedStats": {}, + "appliedTotal": 0.0, + "externalId": "2020", + "id": "002020", + "proTeamId": 0, + "scoringPeriodId": 0, + "seasonId": 2020, + "statSourceId": 0, + "statSplitTypeId": 0, + "stats": {} + }, + { + "appliedAverage": 14.55, + "appliedStats": { + "53": 34.0, + "72": -2.0, + "24": 46.400000000000006, + "25": 24.0, + "42": 25.1, + "43": 18.0 + }, + "appliedTotal": 145.5, + "externalId": "2019", + "id": "002019", + "proTeamId": 0, + "scoringPeriodId": 0, + "seasonId": 2019, + "statSourceId": 0, + "statSplitTypeId": 0, + "stats": { + "23": 116.0, + "24": 464.0, + "25": 4.0, + "27": 90.0, + "28": 44.0, + "29": 20.0, + "30": 13.0, + "31": 3.0, + "32": 1.0, + "33": 20.0, + "34": 8.0, + "37": 1.0, + "39": 4.0, + "40": 46.4, + "41": 34.0, + "42": 251.0, + "43": 3.0, + "47": 46.0, + "48": 21.0, + "49": 9.0, + "50": 7.0, + "51": 2.0, + "53": 34.0, + "54": 2.0, + "58": 38.0, + "59": 298.0, + "60": 7.38235294, + "61": 25.1, + "66": 1.0, + "68": 1.0, + "70": 1.0, + "72": 1.0, + "73": 1.0, + "155": 3.0, + "156": 7.0, + "158": 42.0, + "179": 3.0, + "180": 1.0, + "184": 1.0, + "185": 2.0, + "210": 10.0 + }, + "variance": {} + } + ], + "universeId": 1 + }, + "ratings": { + "0": { + "positionalRanking": 35, + "totalRanking": 126, + "totalRating": 145.5 + } + }, + "rosterLocked": false, + "status": "ONTEAM", + "tradeLocked": false, + "transactions": [ + { + "bidAmount": 0, + "executionType": "EXECUTE", + "id": "c378cd54-4fcd-4249-8a70-0c70af8776ca", + "isActingAsTeamOwner": false, + "isLeagueManager": false, + "isPending": false, + "items": [ + { + "fromLineupSlotId": -1, + "fromTeamId": 0, + "isKeeper": false, + "overallPickNumber": 50, + "playerId": 3045147, + "toLineupSlotId": 2, + "toTeamId": 4, + "type": "DRAFT" + } + ], + "proposedDate": 1594241363881, + "rating": 0, + "scoringPeriodId": 1, + "skipTransactionCounters": false, + "status": "EXECUTED", + "subOrder": 0, + "teamId": 4, + "type": "DRAFT" + } + ] + } + ] +} \ No newline at end of file diff --git a/tests/football/unit/test_league.py b/tests/football/unit/test_league.py index e7ceeb21..8b42d459 100644 --- a/tests/football/unit/test_league.py +++ b/tests/football/unit/test_league.py @@ -16,6 +16,8 @@ def setUp(self): self.draft_data = json.loads(data.read()) with open('tests/football/unit/data/league_players_2018.json') as data: self.players_data = json.loads(data.read()) + with open('tests/football/unit/data/league_2019_playerCard.json') as data: + self.player_card_data = json.loads(data.read()) def mock_setUp(self, m): m.get(self.espn_endpoint + '?view=mTeam&view=mRoster&view=mMatchup&view=mSettings', status_code=200, json=self.league_data) @@ -241,6 +243,21 @@ def test_cookie_set(self, mock_fetch_league): league = League(league_id=1234, year=2019, espn_s2='cookie1', swid='cookie2') self.assertEqual(league.espn_request.cookies['espn_s2'], 'cookie1') self.assertEqual(league.espn_request.cookies['SWID'], 'cookie2') + + @requests_mock.Mocker() + def test_player_info(self, m): + self.mock_setUp(m) + m.get(self.espn_endpoint + '?view=kona_playercard', status_code=200, json=self.player_card_data) + + + league = League(self.league_id, self.season) + # Invalid name + player = league.player_info('Test 1') + self.assertEqual(player, None) + + player = league.player_info('James Conner') + self.assertEqual(player.name, 'James Conner') + self.assertEqual(player.stats[1]['points'], 10.5) From 236bdc9538bf7f52483792fac5e81e145890dc1e Mon Sep 17 00:00:00 2001 From: Christian Date: Sat, 5 Sep 2020 11:56:11 -0700 Subject: [PATCH 4/4] fix auth unit tests --- tests/football/integration/test_league.py | 1 + tests/requests/__init__.py | 0 tests/requests/test_espn_requests.py | 8 ++++---- 3 files changed, 5 insertions(+), 4 deletions(-) create mode 100644 tests/requests/__init__.py diff --git a/tests/football/integration/test_league.py b/tests/football/integration/test_league.py index 9b782c6a..ab3abb87 100644 --- a/tests/football/integration/test_league.py +++ b/tests/football/integration/test_league.py @@ -41,3 +41,4 @@ def test_box_scores(self): self.assertEqual(repr(box_scores[1].away_team), 'Team(TEAM BERRY)') self.assertEqual(repr(box_scores[1].away_lineup[1]), 'Player(Odell Beckham Jr., points:29, projected:16)') + self.assertEqual(repr(box_scores[1]), 'Box Score(Team(TEAM BERRY) at Team(TEAM HOLLAND))') diff --git a/tests/requests/__init__.py b/tests/requests/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/requests/test_espn_requests.py b/tests/requests/test_espn_requests.py index 7ca1e71f..c98ff1c2 100644 --- a/tests/requests/test_espn_requests.py +++ b/tests/requests/test_espn_requests.py @@ -7,7 +7,7 @@ class EspnRequestsTest(TestCase): @requests_mock.Mocker() @mock.patch('sys.stdout', new_callable=io.StringIO) - def test_authentication_api_fail(self, mock_request, mock_stdout, mock_fetch_league): + def test_authentication_api_fail(self, mock_request, mock_stdout): url_api_key = 'https://registerdisney.go.com/jgc/v5/client/ESPN-FANTASYLM-PROD/api-key?langPref=en-US' mock_request.post(url_api_key, status_code=400) request = EspnFantasyRequests(sport='nfl', league_id=1234, year=2019) @@ -16,7 +16,7 @@ def test_authentication_api_fail(self, mock_request, mock_stdout, mock_fetch_lea @requests_mock.Mocker() @mock.patch('sys.stdout', new_callable=io.StringIO) - def test_authentication_login_fail(self, mock_request, mock_stdout, mock_fetch_league): + def test_authentication_login_fail(self, mock_request, mock_stdout): url_api_key = 'https://registerdisney.go.com/jgc/v5/client/ESPN-FANTASYLM-PROD/api-key?langPref=en-US' url_login = 'https://ha.registerdisney.go.com/jgc/v5/client/ESPN-FANTASYLM-PROD/guest/login?langPref=en-US' mock_request.post(url_api_key, headers={'api-key':'None'}, status_code=200) @@ -28,7 +28,7 @@ def test_authentication_login_fail(self, mock_request, mock_stdout, mock_fetch_l @requests_mock.Mocker() @mock.patch('sys.stdout', new_callable=io.StringIO) - def test_authentication_login_error(self, mock_request, mock_stdout, mock_fetch_league): + def test_authentication_login_error(self, mock_request, mock_stdout): url_api_key = 'https://registerdisney.go.com/jgc/v5/client/ESPN-FANTASYLM-PROD/api-key?langPref=en-US' url_login = 'https://ha.registerdisney.go.com/jgc/v5/client/ESPN-FANTASYLM-PROD/guest/login?langPref=en-US' mock_request.post(url_api_key, headers={'api-key':'None'}, status_code=200) @@ -39,7 +39,7 @@ def test_authentication_login_error(self, mock_request, mock_stdout, mock_fetch_ self.assertEqual(mock_stdout.getvalue(), 'Authentication unsuccessful - error:{}\nRetry the authentication or continuing without private league access\n') @requests_mock.Mocker() - def test_authentication_pass(self, mock_request, mock_fetch_league): + def test_authentication_pass(self, mock_request): url_api_key = 'https://registerdisney.go.com/jgc/v5/client/ESPN-FANTASYLM-PROD/api-key?langPref=en-US' url_login = 'https://ha.registerdisney.go.com/jgc/v5/client/ESPN-FANTASYLM-PROD/guest/login?langPref=en-US' mock_request.post(url_api_key, headers={'api-key':'None'}, status_code=200)