import requests from datetime import datetime, timedelta, timezone import zoneinfo class ESPNAPI: BASE_URL = 'https://site.api.espn.com/apis/site/v2/sports/football/nfl' def __init__(self): self.session = requests.Session() def get_player_injury_status(self, player_name): """Get injury status for a specific player from ESPN""" try: # Try to get player info from ESPN API url = f"{self.BASE_URL}/athletes" response = self.session.get(url, params={'search': player_name}) response.raise_for_status() data = response.json() print(f"ESPN API: Searching for {player_name}", flush=True) if 'athletes' in data and len(data['athletes']) > 0: athlete = data['athletes'][0] print(f"ESPN API: Found athlete data for {player_name}: {athlete}", flush=True) # Check for injury status if 'injuries' in athlete: return athlete['injuries'] elif 'status' in athlete: return athlete['status'] return None except Exception as e: print(f"ESPN API: Error fetching injury status for {player_name}: {e}", flush=True) return None def get_week_schedule(self, week, season, user_timezone='America/Los_Angeles'): """Get NFL schedule for a specific week""" try: print(f"ESPN API: Fetching schedule for week {week}, season {season}", flush=True) # Get current NFL scoreboard url = f"{self.BASE_URL}/scoreboard" response = self.session.get(url) response.raise_for_status() data = response.json() print(f"ESPN API: Response status: {response.status_code}", flush=True) games = [] if 'events' in data: print(f"ESPN API: Found {len(data['events'])} events", flush=True) for i, event in enumerate(data['events']): try: # Parse the game date as UTC game_date_utc = datetime.strptime(event['date'], '%Y-%m-%dT%H:%MZ').replace(tzinfo=timezone.utc) # Convert to user's timezone (default PST) try: user_tz = zoneinfo.ZoneInfo(user_timezone) except: # Fallback to PST if timezone is invalid user_tz = zoneinfo.ZoneInfo('America/Los_Angeles') user_timezone = 'America/Los_Angeles' game_date_local = game_date_utc.astimezone(user_tz) # Get timezone abbreviation tz_abbr = game_date_local.strftime('%Z') if not tz_abbr: # Fallback if %Z doesn't work if 'Los_Angeles' in user_timezone or 'Pacific' in user_timezone: tz_abbr = 'PST' if game_date_local.dst() == timedelta(0) else 'PDT' elif 'New_York' in user_timezone or 'Eastern' in user_timezone: tz_abbr = 'EST' if game_date_local.dst() == timedelta(0) else 'EDT' else: tz_abbr = 'Local' # Extract team information and game status competition = event['competitions'][0] competitors = competition['competitors'] # Get game status information status = competition.get('status', {}) game_state = status.get('type', {}).get('state', 'pre') # pre, in, post is_live = game_state == 'in' status_display = status.get('type', {}).get('name', 'Scheduled') home_team = None away_team = None # Identify home and away teams for comp in competitors: team_abbrev = comp['team']['abbreviation'] if comp['homeAway'] == 'home': home_team = team_abbrev else: away_team = team_abbrev print(f"ESPN API: {away_team} @ {home_team} at {game_date_local.strftime('%I:%M %p')} {tz_abbr}", flush=True) # Store game data with user's local times games.append({ 'date': game_date_utc, # Keep UTC for reference 'date_local': game_date_local, 'day_of_week': game_date_local.strftime('%A'), 'date_formatted': game_date_local.strftime('%m/%d'), 'time': f"{game_date_local.strftime('%I:%M %p')} {tz_abbr}", 'home_team': home_team, 'away_team': away_team, 'teams': [home_team, away_team], 'is_past': game_date_local < datetime.now(game_date_local.tzinfo), 'is_live': is_live, 'game_state': game_state, 'status_display': status_display }) except Exception as e: print(f"ESPN API: Error processing event {i+1}: {str(e)}", flush=True) else: print("ESPN API: No 'events' key found in response", flush=True) print(f"ESPN API: Processed {len(games)} games total", flush=True) schedule = self._organize_by_day(games) # Log games by day for day, day_games in schedule.items(): print(f"ESPN API: {day}: {len(day_games)} games", flush=True) return schedule except Exception as e: print(f"ESPN API: Error fetching schedule: {e}", flush=True) return {} def _organize_by_day(self, games): """Organize games by day, sorted chronologically with date info""" schedule = {} # Sort games by date first games_sorted = sorted(games, key=lambda x: x['date_local']) # Group games by day for game in games_sorted: day_key = f"{game['day_of_week']} {game['date_formatted']}" if day_key not in schedule: schedule[day_key] = { 'day_name': game['day_of_week'], 'date': game['date_formatted'], 'date_obj': game['date_local'].date(), 'is_past': game['date_local'].date() < datetime.now(game['date_local'].tzinfo).date(), 'games': [] } schedule[day_key]['games'].append(game) # Sort games within each day by time for day_info in schedule.values(): day_info['games'].sort(key=lambda x: x['date_local']) return schedule