""" PD API client for fetching player position ratings. Integrates with Paper Dynasty API to retrieve defensive ratings for use in X-Check resolution. Author: Claude Date: 2025-11-03 """ import logging import httpx from typing import List, Optional from app.models.player_models import PositionRating logger = logging.getLogger(f'{__name__}.PdApiClient') class PdApiClient: """Client for PD API position rating lookups.""" def __init__(self, base_url: str = "https://pd.manticorum.com"): """ Initialize PD API client. Args: base_url: Base URL for PD API (default: production) """ self.base_url = base_url self.timeout = httpx.Timeout(10.0, connect=5.0) async def get_position_ratings( self, player_id: int, positions: Optional[List[str]] = None ) -> List[PositionRating]: """ Fetch all position ratings for a player. Args: player_id: PD player ID positions: Optional list of positions to filter (e.g., ['SS', '2B', 'LF']) If None, returns all positions for player Returns: List of PositionRating objects (one per position played) Raises: httpx.HTTPError: If API request fails Example: # Get all positions for player 8807 ratings = await client.get_position_ratings(8807) # Get only infield positions ratings = await client.get_position_ratings(8807, ['SS', '2B', '3B']) """ # Build URL with query parameters url = f"{self.base_url}/api/v2/cardpositions" params = {"player_id": player_id} # Add position filters if specified if positions: # httpx will handle multiple values for same parameter params["position"] = positions try: async with httpx.AsyncClient(timeout=self.timeout) as client: response = await client.get(url, params=params) response.raise_for_status() data = response.json() # Parse positions from API response position_ratings = [] # API returns list of position objects directly if isinstance(data, list): for pos_data in data: position_ratings.append(PositionRating.from_api_response(pos_data)) # Or may be wrapped in 'positions' key elif isinstance(data, dict) and 'positions' in data: for pos_data in data['positions']: position_ratings.append(PositionRating.from_api_response(pos_data)) logger.info(f"Loaded {len(position_ratings)} position ratings for player {player_id}") return position_ratings except httpx.HTTPError as e: logger.error(f"Failed to fetch position ratings for player {player_id}: {e}") raise except Exception as e: logger.error(f"Unexpected error fetching ratings for player {player_id}: {e}") raise # Singleton instance pd_api_client = PdApiClient()