Skip to content

Commit

Permalink
Include Total Points in player_stats return (#52)
Browse files Browse the repository at this point in the history
I have updated the player_stats command to leverage the League resource
from the Yahoo API instead of the Player resource. This allows us to
return the total points and all the stats details. There are a few other
benefits IMO:

- Makes the library more predictable as the league class is now using
the league resource instead of an edge case where it uses the player
resource
- We are only gaining data here the league /stats endpoint returns the
same values as the players /stats endpoint
- Allows us to simplify the mock for player_stats

---------

Co-authored-by: DMcP89 <[email protected]>
  • Loading branch information
DMcP89 and DMcP89 authored Sep 18, 2024
1 parent 3ba8bd9 commit 6b26e6b
Show file tree
Hide file tree
Showing 11 changed files with 283 additions and 20 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,4 @@ docs/_build
.vscode/
.envrc
build/
.python-version
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ def readme():


setup(name='yahoo_fantasy_api',
version='2.9.0',
version='2.9.1',
description='Python bindings to access the Yahoo! Fantasy APIs',
long_description=readme(),
url='http://github.com/spilchen/yahoo_fantasy_api',
Expand Down
11 changes: 7 additions & 4 deletions yahoo_fantasy_api/league.py
Original file line number Diff line number Diff line change
Expand Up @@ -708,7 +708,7 @@ def player_stats(self, player_ids, req_type, date=None, week=None, season=None):
while len(player_ids) > 0:
next_player_ids = player_ids[0:25]
player_ids = player_ids[25:]
stats += self._fetch_plyr_stats(game_code, next_player_ids,
stats += self._fetch_plyr_stats(next_player_ids,
req_type, date, week, season)
return stats

Expand Down Expand Up @@ -789,7 +789,7 @@ def transactions(self, tran_types, count):
transactions.append({**transaction_details, **players})
return transactions

def _fetch_plyr_stats(self, game_code, player_ids, req_type, date, week, season):
def _fetch_plyr_stats(self, player_ids, req_type, date, week, season):
'''
Fetch player stats for at most 25 player IDs.
Expand All @@ -803,12 +803,12 @@ def _fetch_plyr_stats(self, game_code, player_ids, req_type, date, week, season)
:rtype: list(dict)
'''
assert(len(player_ids) > 0 and len(player_ids) <= 25)
json = self.yhandler.get_player_stats_raw(game_code, player_ids,
json = self.yhandler.get_player_stats_raw(self.league_id, player_ids,
req_type, date, week, season)
t = objectpath.Tree(json)
stats = []
row = None
for e in t.execute('$..(full,player_id,position_type,stat)'):
for e in t.execute('$..(full,player_id,position_type,stat,total)'):
if 'player_id' in e:
if row is not None:
stats.append(row)
Expand All @@ -826,6 +826,9 @@ def _fetch_plyr_stats(self, game_code, player_ids, req_type, date, week, season)
val = e['stat']['value']
if stat_id in self.stats_id_map:
row[self.stats_id_map[stat_id]] = val
elif 'total' in e:
row['total_points'] = e['total']

if row is not None:
stats.append(row)
return stats
Expand Down
4 changes: 2 additions & 2 deletions yahoo_fantasy_api/team.py
Original file line number Diff line number Diff line change
Expand Up @@ -402,7 +402,7 @@ def _construct_change_roster_xml(self, time_frame, modified_lineup):
p = plyrs.appendChild(doc.createElement('player'))
p.appendChild(doc.createElement('player_key')) \
.appendChild(doc.createTextNode('{}.p.{}'.format(
self.league_prefix, int(plyr['player_id']))))
self.league_prefix, int(plyr['player_id']))))
p.appendChild(doc.createElement('position')) \
.appendChild(doc.createTextNode(plyr['selected_position']))

Expand Down Expand Up @@ -437,7 +437,7 @@ def _construct_transaction_player_xml(self, doc, root, player_id, action):
player = root.appendChild(doc.createElement('player'))
player.appendChild(doc.createElement('player_key')) \
.appendChild(doc.createTextNode('{}.p.{}'.format(
self.league_prefix, int(player_id))))
self.league_prefix, int(player_id))))
tdata = player.appendChild(doc.createElement('transaction_data'))
tdata.appendChild(doc.createElement('type')) \
.appendChild(doc.createTextNode(action))
Expand Down
7 changes: 7 additions & 0 deletions yahoo_fantasy_api/tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,13 @@ def mock_nhl_league(sc):
yield lg


@pytest.fixture()
def mock_nfl_league(sc):
lg = yfa.League(sc, '449.l.75178')
lg.inject_yhandler(mock_yhandler.YHandler())
yield lg


@pytest.fixture()
def mock_team(sc):
tm = yfa.Team(sc, '268.l.46645')
Expand Down
9 changes: 2 additions & 7 deletions yahoo_fantasy_api/tests/mock_yhandler.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,13 +132,9 @@ def get_team_transactions(self, league_id, team_key, tran_type):
with open(fn, "r") as f:
return json.load(f)

def get_player_stats_raw(self, game_code, player_ids, req_type, day,
def get_player_stats_raw(self, league_id, player_ids, req_type, day,
week, season):
if game_code == 'nhl':
id = "396.l.21484"
else:
id = "388.l.27081"
fn = "{}/sample.player_stats.{}.json".format(self.dir_path, id)
fn = "{}/sample.player_stats.{}.json".format(self.dir_path, league_id)
with open(fn, "r") as f:
return json.load(f)

Expand Down Expand Up @@ -194,4 +190,3 @@ def put_roster(self, team_key, xml):
# This produces no output. Just save the xml for inspection by the
# test.
self.roster_xml = xml

249 changes: 249 additions & 0 deletions yahoo_fantasy_api/tests/sample.player_stats.449.l.75178.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,249 @@
{
"fantasy_content": {
"xml:lang": "en-US",
"yahoo:uri": "\/fantasy\/v2\/league\/449.l.751781\/players;player_keys=449.p.7200\/stats;type=week;week=1",
"league": [
{
"league_key": "449.l.751781",
"league_id": "751781",
"name": "Harambe Memorial League",
"url": "https:\/\/football.fantasysports.yahoo.com\/f1\/751781",
"logo_url": false,
"draft_status": "postdraft",
"num_teams": 12,
"edit_key": "2",
"weekly_deadline": "",
"league_update_timestamp": "1726123385",
"scoring_type": "head",
"league_type": "private",
"renew": "423_71785",
"renewed": "",
"felo_tier": "silver",
"iris_group_chat_id": "",
"allow_add_to_dl_extra_pos": 0,
"is_pro_league": "0",
"is_cash_league": "0",
"current_week": 2,
"start_week": "1",
"start_date": "2024-09-05",
"end_week": "17",
"end_date": "2024-12-30",
"is_plus_league": "0",
"game_code": "nfl",
"season": "2024"
},
{
"players": {
"0": {
"player": [
[
{
"player_key": "449.p.7200"
},
{
"player_id": "7200"
},
{
"name": {
"full": "Aaron Rodgers",
"first": "Aaron",
"last": "Rodgers",
"ascii_first": "Aaron",
"ascii_last": "Rodgers"
}
},
{
"url": "https:\/\/sports.yahoo.com\/nfl\/players\/7200"
},
{
"editorial_player_key": "nfl.p.7200"
},
{
"editorial_team_key": "nfl.t.20"
},
{
"editorial_team_full_name": "New York Jets"
},
{
"editorial_team_abbr": "NYJ"
},
{
"editorial_team_url": "https:\/\/sports.yahoo.com\/nfl\/teams\/ny-jets\/"
},
{
"bye_weeks": {
"week": "12"
}
},
{
"is_keeper": {
"status": false,
"cost": false,
"kept": false
}
},
{
"uniform_number": "8"
},
{
"display_position": "QB"
},
{
"headshot": {
"url": "https:\/\/s.yimg.com\/iu\/api\/res\/1.2\/8MiUmLsQnH2U8RAK8U0goA--~C\/YXBwaWQ9eXNwb3J0cztjaD0yMzM2O2NyPTE7Y3c9MTc5MDtkeD04NTc7ZHk9MDtmaT11bGNyb3A7aD02MDtxPTEwMDt3PTQ2\/https:\/\/s.yimg.com\/xe\/i\/us\/sp\/v\/nfl_cutout\/players_l\/09092024\/7200.png",
"size": "small"
},
"image_url": "https:\/\/s.yimg.com\/iu\/api\/res\/1.2\/8MiUmLsQnH2U8RAK8U0goA--~C\/YXBwaWQ9eXNwb3J0cztjaD0yMzM2O2NyPTE7Y3c9MTc5MDtkeD04NTc7ZHk9MDtmaT11bGNyb3A7aD02MDtxPTEwMDt3PTQ2\/https:\/\/s.yimg.com\/xe\/i\/us\/sp\/v\/nfl_cutout\/players_l\/09092024\/7200.png"
},
{
"is_undroppable": "0"
},
{
"position_type": "O"
},
{
"primary_position": "QB"
},
{
"eligible_positions": [
{
"position": "QB"
}
]
},
{
"eligible_positions_to_add": []
},
[],
{
"has_player_notes": 1
},
[],
{
"player_notes_last_timestamp": 1725939762
}
],
{
"player_stats": {
"0": {
"coverage_type": "week",
"week": "1"
},
"stats": [
{
"stat": {
"stat_id": "4",
"value": "167"
}
},
{
"stat": {
"stat_id": "5",
"value": "1"
}
},
{
"stat": {
"stat_id": "6",
"value": "1"
}
},
{
"stat": {
"stat_id": "8",
"value": "1"
}
},
{
"stat": {
"stat_id": "9",
"value": "-1"
}
},
{
"stat": {
"stat_id": "10",
"value": "0"
}
},
{
"stat": {
"stat_id": "11",
"value": "0"
}
},
{
"stat": {
"stat_id": "12",
"value": "0"
}
},
{
"stat": {
"stat_id": "13",
"value": "0"
}
},
{
"stat": {
"stat_id": "15",
"value": "0"
}
},
{
"stat": {
"stat_id": "16",
"value": "0"
}
},
{
"stat": {
"stat_id": "17",
"value": "0"
}
},
{
"stat": {
"stat_id": "18",
"value": "0"
}
},
{
"stat": {
"stat_id": "58",
"value": "0"
}
},
{
"stat": {
"stat_id": "78",
"value": "0"
}
},
{
"stat": {
"stat_id": "57",
"value": "0"
}
}
]
},
"player_points": {
"0": {
"coverage_type": "week",
"week": "1"
},
"total": "8.58"
}
}
]
},
"count": 1
}
}
],
"time": "22.672176361084ms",
"copyright": "Certain Data by Sportradar, Stats Perform and Rotowire",
"refresh_rate": "60"
}
}
6 changes: 6 additions & 0 deletions yahoo_fantasy_api/tests/test_league.py
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,12 @@ def test_nhl_player_stats(mock_nhl_league):
assert(stats[0]['PTS'] == 35)


def test_nfl_player_stats(mock_nfl_league):
stats = mock_nfl_league.player_stats([7200], 'season')
assert(stats[0]['name'] == 'Aaron Rodgers')
assert(stats[0]['total_points'] == '8.58')


def test_draft_results(mock_nhl_league):
dres = mock_nhl_league.draft_results()
print(dres)
Expand Down
3 changes: 2 additions & 1 deletion yahoo_fantasy_api/tests/test_team.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,8 @@ def test__construct_trade_proposal_xml(mock_team):
your_player_keys = ['248.p.4130']
their_player_keys = ['248.p.2415']

actual_xml = mock_team._construct_trade_proposal_xml(tradee_team_key, your_player_keys, their_player_keys, trade_note)
actual_xml = mock_team._construct_trade_proposal_xml(
tradee_team_key, your_player_keys, their_player_keys, trade_note)

assert actual_xml == expected_xml

Expand Down
Loading

0 comments on commit 6b26e6b

Please sign in to comment.