From f0637bd0222a4c7d33b9283ed1dd6d5df7307f5d Mon Sep 17 00:00:00 2001 From: John Diebold <114956466+JohnDiebold@users.noreply.github.com> Date: Sun, 2 Feb 2025 14:32:19 -0500 Subject: [PATCH] Feature/Add player news --- espn_api/basketball/league.py | 11 ++++++++--- espn_api/basketball/player.py | 14 ++++++++++++-- espn_api/requests/constant.py | 1 + espn_api/requests/espn_requests.py | 17 ++++++++++++++++- 4 files changed, 37 insertions(+), 6 deletions(-) diff --git a/espn_api/basketball/league.py b/espn_api/basketball/league.py index fbc3a799..f19daa45 100644 --- a/espn_api/basketball/league.py +++ b/espn_api/basketball/league.py @@ -195,7 +195,7 @@ def box_scores(self, matchup_period: int = None, scoring_period: int = None, mat matchup.away_team = team return box_data - def player_info(self, name: str = None, playerId: Union[int, list] = None) -> Union[Player, List[Player]]: + def player_info(self, name: str = None, playerId: Union[int, list] = None, include_news = False) -> Union[Player, List[Player]]: ''' Returns Player class if name found ''' if name: @@ -209,7 +209,12 @@ def player_info(self, name: str = None, playerId: Union[int, list] = None) -> Un pro_schedule = self._get_all_pro_schedule() + if include_news: + news = {} + for id in playerId: + news[id] = self.espn_request.get_player_news(id) + if len(data['players']) == 1: - return Player(data['players'][0], self.year, pro_schedule) + return Player(data['players'][0], self.year, pro_schedule, news=news.get(playerId[0], []) if include_news else None) if len(data['players']) > 1: - return [Player(player, self.year, pro_schedule) for player in data['players']] + return [Player(player, self.year, pro_schedule, news=news.get(player['id'], []) if include_news else None) for player in data['players']] diff --git a/espn_api/basketball/player.py b/espn_api/basketball/player.py index 2182495e..cd5ed6af 100644 --- a/espn_api/basketball/player.py +++ b/espn_api/basketball/player.py @@ -5,7 +5,7 @@ class Player(object): '''Player are part of team''' - def __init__(self, data, year, pro_team_schedule = None): + def __init__(self, data, year, pro_team_schedule = None, news = None): self.name = json_parsing(data, 'fullName') self.playerId = json_parsing(data, 'id') self.year = year @@ -18,6 +18,7 @@ def __init__(self, data, year, pro_team_schedule = None): self.posRank = json_parsing(data, 'positionalRanking') self.stats = {} self.schedule = {} + self.news = {} if pro_team_schedule: pro_team_id = json_parsing(data, 'proTeamId') @@ -27,7 +28,16 @@ def __init__(self, data, year, pro_team_schedule = None): team = game['awayProTeamId'] if game['awayProTeamId'] != pro_team_id else game['homeProTeamId'] self.schedule[key] = { 'team': PRO_TEAM_MAP[team], 'date': datetime.fromtimestamp(game['date']/1000.0) } - + if news: + news_feed = news.get("news", {}).get("feed", []) + self.news = [ + { + "published": item.get("published", ""), + "headline": item.get("headline", ""), + "story": item.get("story", "") + } + for item in news_feed + ] # add available stats diff --git a/espn_api/requests/constant.py b/espn_api/requests/constant.py index 853a94f0..46f4b3e3 100644 --- a/espn_api/requests/constant.py +++ b/espn_api/requests/constant.py @@ -1,4 +1,5 @@ FANTASY_BASE_ENDPOINT = 'https://lm-api-reads.fantasy.espn.com/apis/v3/games/' +NEWS_BASE_ENDPOINT = 'https://site.api.espn.com/apis/fantasy/v3/games/' FANTASY_SPORTS = { 'nfl' : 'ffl', 'nba' : 'fba', diff --git a/espn_api/requests/espn_requests.py b/espn_api/requests/espn_requests.py index c60e78ac..9df23c94 100644 --- a/espn_api/requests/espn_requests.py +++ b/espn_api/requests/espn_requests.py @@ -1,6 +1,6 @@ import requests import json -from .constant import FANTASY_BASE_ENDPOINT, FANTASY_SPORTS +from .constant import FANTASY_BASE_ENDPOINT, NEWS_BASE_ENDPOINT, FANTASY_SPORTS from ..utils.logger import Logger from typing import List @@ -24,6 +24,7 @@ def __init__(self, sport: str, year: int, league_id: int, cookies: dict = None, self.year = year self.league_id = league_id self.ENDPOINT = FANTASY_BASE_ENDPOINT + FANTASY_SPORTS[sport] + '/seasons/' + str(self.year) + self.NEWS_ENDPOINT = NEWS_BASE_ENDPOINT + FANTASY_SPORTS[sport] + '/news/' + 'players' self.cookies = cookies self.logger = logger @@ -86,6 +87,14 @@ def get(self, params: dict = None, headers: dict = None, extend: str = ''): if self.logger: self.logger.log_request(endpoint=endpoint, params=params, headers=headers, response=r.json()) return r.json() + + def news_get(self, params: dict = None, headers: dict = None, extend: str = ''): + endpoint = self.NEWS_ENDPOINT + extend + r = requests.get(endpoint, params=params, headers=headers, cookies=self.cookies) + + if self.logger: + self.logger.log_request(endpoint=endpoint, params=params, headers=headers, response=r.json()) + return r.json() def get_league(self): '''Gets all of the leagues initial data (teams, roster, matchups, settings)''' @@ -152,6 +161,12 @@ def get_player_card(self, playerIds: List[int], max_scoring_period: int, additio data = self.league_get(params=params, headers=headers) return data + def get_player_news(self, playerId): + '''Gets the player news''' + params = {'playerId': playerId} + data = self.news_get(params=params) + return data + # Username and password no longer works using their API without using google recaptcha # Possibly revisit in future if anything changes