""" SBA API client for fetching player data. Integrates with SBA REST API to retrieve player information for use in game lineup display. Author: Claude Date: 2025-01-10 """ import logging from typing import Dict, Any, List, Optional import httpx from app.models.player_models import SbaPlayer logger = logging.getLogger(f'{__name__}.SbaApiClient') class SbaApiClient: """Client for SBA API player data lookups.""" def __init__(self, base_url: str = "https://api.sba.manticorum.com"): """ Initialize SBA API client. Args: base_url: Base URL for SBA API (default: production) """ self.base_url = base_url self.timeout = httpx.Timeout(10.0, connect=5.0) async def get_player(self, player_id: int) -> SbaPlayer: """ Fetch player data from SBA API. Args: player_id: SBA player ID Returns: SbaPlayer instance with all player data Raises: httpx.HTTPError: If API request fails Example: player = await client.get_player(12288) print(f"Name: {player.name}") # "Ronald Acuna Jr" print(f"Positions: {player.get_positions()}") # ['RF'] """ url = f"{self.base_url}/players/{player_id}" try: async with httpx.AsyncClient(timeout=self.timeout) as client: response = await client.get(url) response.raise_for_status() data = response.json() player = SbaPlayer.from_api_response(data) logger.info(f"Loaded player {player_id}: {player.name}") return player except httpx.HTTPError as e: logger.error(f"Failed to fetch player {player_id}: {e}") raise except Exception as e: logger.error(f"Unexpected error fetching player {player_id}: {e}") raise async def get_players_batch( self, player_ids: List[int] ) -> Dict[int, SbaPlayer]: """ Fetch multiple players in parallel. Args: player_ids: List of SBA player IDs to fetch Returns: Dictionary mapping player_id to SbaPlayer instance Players that fail to load will be omitted from the result Example: players = await client.get_players_batch([12288, 12289, 12290]) for player_id, player in players.items(): print(f"{player.name}: {player.get_positions()}") """ if not player_ids: return {} results: Dict[int, SbaPlayer] = {} async with httpx.AsyncClient(timeout=self.timeout) as client: for player_id in player_ids: try: url = f"{self.base_url}/players/{player_id}" response = await client.get(url) response.raise_for_status() data = response.json() player = SbaPlayer.from_api_response(data) results[player_id] = player except httpx.HTTPError as e: logger.warning(f"Failed to fetch player {player_id}: {e}") # Continue with other players except Exception as e: logger.warning(f"Unexpected error fetching player {player_id}: {e}") # Continue with other players logger.info(f"Loaded {len(results)}/{len(player_ids)} players") return results # Singleton instance sba_api_client = SbaApiClient()