From f3b87555c37327e34a7246f29dfa3356315f6bdf Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 13 Aug 2024 19:20:14 -0700 Subject: [PATCH 1/4] Add optional week param to team.change_positions() to use in NFL leagues --- yahoo_fantasy_api/team.py | 33 ++++++++++++++++++++------------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/yahoo_fantasy_api/team.py b/yahoo_fantasy_api/team.py index 02e7155..9bc1420 100644 --- a/yahoo_fantasy_api/team.py +++ b/yahoo_fantasy_api/team.py @@ -113,28 +113,29 @@ def _compact_eligible_pos(j): pass return roster - def change_positions(self, day, modified_lineup): + def change_positions(self, modified_lineup, day=None, week=None): """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 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. :type modified_lineup: list(dict) + :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 week: Week number that the new positions take affect + :type week: int >>> import datetime cd = datetime.date(2019, 10, 7) plyrs = [{'player_id': 5981, 'selected_position': 'BN'}, {'player_id': 4558, 'selected_position': 'BN'}] - tm.change_positions(cd, plyrs) + tm.change_positions(plyrs, cd) """ - xml = self._construct_change_roster_xml(day, modified_lineup) + xml = self._construct_change_roster_xml(modified_lineup, day, week) self.yhandler.put_roster(self.team_key, xml) def add_player(self, player_id): @@ -377,16 +378,22 @@ 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, modified_lineup, day, week): """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 week is not None: + roster.appendChild(doc.createElement('coverage_type')) \ + .appendChild(doc.createTextNode('week')) + roster.appendChild(doc.createElement('week')) \ + .appendChild(doc.createTextNode(str(week))) + else: + roster.appendChild(doc.createElement('coverage_type')) \ + .appendChild(doc.createTextNode('date')) + roster.appendChild(doc.createElement('date')) \ + .appendChild(doc.createTextNode(day.strftime("%Y-%m-%d"))) plyrs = roster.appendChild(doc.createElement('players')) for plyr in modified_lineup: From b211d1f9db82637fe5ac052cab8ee0ab5e8570a3 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 19 Aug 2024 20:01:20 -0700 Subject: [PATCH 2/4] Replace day with time_frame and bump version --- setup.py | 2 +- yahoo_fantasy_api/team.py | 31 ++++++++++++++++--------------- 2 files changed, 17 insertions(+), 16 deletions(-) diff --git a/setup.py b/setup.py index e82cb88..26918e9 100755 --- a/setup.py +++ b/setup.py @@ -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', diff --git a/yahoo_fantasy_api/team.py b/yahoo_fantasy_api/team.py index 9bc1420..ec14d42 100644 --- a/yahoo_fantasy_api/team.py +++ b/yahoo_fantasy_api/team.py @@ -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 @@ -113,29 +114,27 @@ def _compact_eligible_pos(j): pass return roster - def change_positions(self, modified_lineup, day=None, week=None): + 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 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. :type modified_lineup: list(dict) - :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 week: Week number that the new positions take affect - :type week: int >>> import datetime cd = datetime.date(2019, 10, 7) plyrs = [{'player_id': 5981, 'selected_position': 'BN'}, {'player_id': 4558, 'selected_position': 'BN'}] - tm.change_positions(plyrs, cd) + tm.change_positions(cd, plyrs) """ - xml = self._construct_change_roster_xml(modified_lineup, day, week) + xml = self._construct_change_roster_xml(time_frame, modified_lineup) self.yhandler.put_roster(self.team_key, xml) def add_player(self, player_id): @@ -378,22 +377,24 @@ def _construct_trade_proposal_xml(self, tradee_team_key: str, your_player_keys: return doc.toprettyxml() - def _construct_change_roster_xml(self, modified_lineup, day, week): + 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')) - if week is not None: + 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(week))) + .appendChild(doc.createTextNode(str(time_frame))) else: - roster.appendChild(doc.createElement('coverage_type')) \ - .appendChild(doc.createTextNode('date')) - roster.appendChild(doc.createElement('date')) \ - .appendChild(doc.createTextNode(day.strftime("%Y-%m-%d"))) + raise RuntimeError("Invalid time_frame format") plyrs = roster.appendChild(doc.createElement('players')) for plyr in modified_lineup: From 0785b29cff91a03048b03e63aa8e6e11a2bd9a19 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 19 Aug 2024 20:03:58 -0700 Subject: [PATCH 3/4] fix spacing --- yahoo_fantasy_api/team.py | 1 + 1 file changed, 1 insertion(+) diff --git a/yahoo_fantasy_api/team.py b/yahoo_fantasy_api/team.py index ec14d42..55f61f8 100644 --- a/yahoo_fantasy_api/team.py +++ b/yahoo_fantasy_api/team.py @@ -119,6 +119,7 @@ def change_positions(self, time_frame, modified_lineup): This raises a RuntimeError if any error occurs when communicating with Yahoo! + :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 From 0699b480d4723eb4a1d754f45ed488735ebeaeae Mon Sep 17 00:00:00 2001 From: Matt Spilchen Date: Thu, 22 Aug 2024 23:03:41 -0300 Subject: [PATCH 4/4] Add some tests for the changed API --- yahoo_fantasy_api/team.py | 8 ++++---- yahoo_fantasy_api/tests/mock_yhandler.py | 6 ++++++ yahoo_fantasy_api/tests/test_team.py | 18 ++++++++++++++++++ 3 files changed, 28 insertions(+), 4 deletions(-) diff --git a/yahoo_fantasy_api/team.py b/yahoo_fantasy_api/team.py index 55f61f8..7ffc806 100644 --- a/yahoo_fantasy_api/team.py +++ b/yahoo_fantasy_api/team.py @@ -119,7 +119,7 @@ def change_positions(self, time_frame, modified_lineup): This raises a RuntimeError if any error occurs when communicating with Yahoo! - + :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 @@ -383,19 +383,19 @@ def _construct_change_roster_xml(self, time_frame, modified_lineup): doc = Document() roster = doc.appendChild(doc.createElement('fantasy_content')) \ .appendChild(doc.createElement('roster')) - + 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): + 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") + raise RuntimeError("Invalid time_frame format. Must be datetime.date or int.") plyrs = roster.appendChild(doc.createElement('players')) for plyr in modified_lineup: diff --git a/yahoo_fantasy_api/tests/mock_yhandler.py b/yahoo_fantasy_api/tests/mock_yhandler.py index 065b01b..1892346 100644 --- a/yahoo_fantasy_api/tests/mock_yhandler.py +++ b/yahoo_fantasy_api/tests/mock_yhandler.py @@ -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 + diff --git a/yahoo_fantasy_api/tests/test_team.py b/yahoo_fantasy_api/tests/test_team.py index a15de5b..d4cb175 100644 --- a/yahoo_fantasy_api/tests/test_team.py +++ b/yahoo_fantasy_api/tests/test_team.py @@ -1,6 +1,8 @@ #!/bin/python import os +import datetime +import pytest def test_matchup(mock_team): @@ -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 "2019-10-07" in mock_team.yhandler.roster_xml + + mock_team.change_positions(2, plyrs) + assert "2019-10-07" not in mock_team.yhandler.roster_xml + assert "2" in mock_team.yhandler.roster_xml + + with pytest.raises(Exception): + mock_team.change_positions("3", plyrs)