Skip to content

Commit

Permalink
Update day parameter in team.change_positions() to time_frame (#50)
Browse files Browse the repository at this point in the history
Position change for NFL leagues requires week rather than date, see
documentation below:


![image](https://github.com/user-attachments/assets/367b2221-148e-45ee-9585-cb1a5f871c47)

This pull request replaces the day parameter with a more generic
time_frame in the change_positions method in the Team class.
This argument may be either a datetime.date or week number for use in
NFL leagues.

---------

Co-authored-by: Matt Spilchen <[email protected]>
  • Loading branch information
jzaturensky and spilchen authored Aug 23, 2024
1 parent 46526ce commit 86889e3
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 11 deletions.
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.8.0',
version='2.9.0',
description='Python bindings to access the Yahoo! Fantasy APIs',
long_description=readme(),
url='http://github.com/spilchen/yahoo_fantasy_api',
Expand Down
29 changes: 19 additions & 10 deletions yahoo_fantasy_api/team.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

from yahoo_fantasy_api import yhandler
import objectpath
import datetime
from xml.dom.minidom import Document

from yahoo_fantasy_api.utils import create_element
Expand Down Expand Up @@ -113,15 +114,15 @@ def _compact_eligible_pos(j):
pass
return roster

def change_positions(self, day, modified_lineup):
def change_positions(self, time_frame, modified_lineup):
"""Change the starting position of a subset of players in your lineup
This raises a RuntimeError if any error occurs when communicating with
Yahoo!
:param day: The day that the new positions take affect. This should be
the starting day of the week.
:type day: :class:`datetime.date`
:param time_frame: The time frame that the new positions take affect. This should be
the starting day of the week (MLB, NBA, or NHL) or the week number (NFL).
:type time_frame: :class:`datetime.date` | int
:param modified_lineup: List of players to modify. Each entry should
have a dict with the following keys: player_id - player ID of the
player to change; selected_position - new position of the player.
Expand All @@ -134,7 +135,7 @@ def change_positions(self, day, modified_lineup):
{'player_id': 4558, 'selected_position': 'BN'}]
tm.change_positions(cd, plyrs)
"""
xml = self._construct_change_roster_xml(day, modified_lineup)
xml = self._construct_change_roster_xml(time_frame, modified_lineup)
self.yhandler.put_roster(self.team_key, xml)

def add_player(self, player_id):
Expand Down Expand Up @@ -377,16 +378,24 @@ def _construct_trade_proposal_xml(self, tradee_team_key: str, your_player_keys:

return doc.toprettyxml()

def _construct_change_roster_xml(self, day, modified_lineup):
def _construct_change_roster_xml(self, time_frame, modified_lineup):
"""Construct XML to pass to Yahoo! that will modified the positions"""
doc = Document()
roster = doc.appendChild(doc.createElement('fantasy_content')) \
.appendChild(doc.createElement('roster'))

roster.appendChild(doc.createElement('coverage_type')) \
.appendChild(doc.createTextNode('date'))
roster.appendChild(doc.createElement('date')) \
.appendChild(doc.createTextNode(day.strftime("%Y-%m-%d")))
if isinstance(time_frame, datetime.date):
roster.appendChild(doc.createElement('coverage_type')) \
.appendChild(doc.createTextNode('date'))
roster.appendChild(doc.createElement('date')) \
.appendChild(doc.createTextNode(time_frame.strftime("%Y-%m-%d")))
elif isinstance(time_frame, int):
roster.appendChild(doc.createElement('coverage_type')) \
.appendChild(doc.createTextNode('week'))
roster.appendChild(doc.createElement('week')) \
.appendChild(doc.createTextNode(str(time_frame)))
else:
raise RuntimeError("Invalid time_frame format. Must be datetime.date or int.")

plyrs = roster.appendChild(doc.createElement('players'))
for plyr in modified_lineup:
Expand Down
6 changes: 6 additions & 0 deletions yahoo_fantasy_api/tests/mock_yhandler.py
Original file line number Diff line number Diff line change
Expand Up @@ -189,3 +189,9 @@ def get_transactions_raw(self, league_id, tran_types, count):
"""
with open(self.dir_path + "/sample.transactions.json", "r") as f:
return json.load(f)

def put_roster(self, team_key, xml):
# This produces no output. Just save the xml for inspection by the
# test.
self.roster_xml = xml

18 changes: 18 additions & 0 deletions yahoo_fantasy_api/tests/test_team.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#!/bin/python

import os
import datetime
import pytest


def test_matchup(mock_team):
Expand Down Expand Up @@ -79,3 +81,19 @@ def test__construct_trade_proposal_xml(mock_team):
actual_xml = mock_team._construct_trade_proposal_xml(tradee_team_key, your_player_keys, their_player_keys, trade_note)

assert actual_xml == expected_xml


def test_change_roster(mock_team):
plyrs = [{'player_id': 5981, 'selected_position': 'BN'},
{'player_id': 4558, 'selected_position': 'BN'}]
cd = datetime.date(2019, 10, 7)
mock_team.change_positions(cd, plyrs)
assert mock_team.yhandler.roster_xml is not None
assert "<date>2019-10-07</date>" in mock_team.yhandler.roster_xml

mock_team.change_positions(2, plyrs)
assert "<date>2019-10-07</date>" not in mock_team.yhandler.roster_xml
assert "<week>2</week>" in mock_team.yhandler.roster_xml

with pytest.raises(Exception):
mock_team.change_positions("3", plyrs)

0 comments on commit 86889e3

Please sign in to comment.