import httpx from typing import Optional from app.core.config import settings class AuthAPIError(Exception): """Exception raised when external auth API returns an error.""" def __init__(self, message: str, status_code: int = 400): self.message = message self.status_code = status_code super().__init__(self.message) class AuthAPIConnectionError(Exception): """Exception raised when unable to connect to auth API.""" pass async def verify_credentials(email: str, password: str) -> dict: """ Verify user credentials against the external auth API. Args: email: User's email address password: User's password Returns: dict: User info from auth API if successful Raises: AuthAPIError: If credentials are invalid AuthAPIConnectionError: If unable to connect to auth API """ try: async with httpx.AsyncClient(timeout=10.0) as client: response = await client.post( f"{settings.AUTH_API_URL}/api/auth/login", json={"username": email, "password": password}, ) if response.status_code == 200: return response.json() elif response.status_code == 401: raise AuthAPIError("Invalid credentials", 401) else: raise AuthAPIError( f"Authentication failed: {response.text}", response.status_code ) except httpx.ConnectError: raise AuthAPIConnectionError("Unable to connect to authentication service") except httpx.TimeoutException: raise AuthAPIConnectionError("Authentication service timeout") async def validate_token(token: str) -> Optional[dict]: """ Validate a token with the external auth API. Args: token: The auth token to validate Returns: dict: Token payload if valid, None if invalid """ try: async with httpx.AsyncClient(timeout=10.0) as client: response = await client.get( f"{settings.AUTH_API_URL}/api/auth/validate", headers={"Authorization": f"Bearer {token}"}, ) if response.status_code == 200: return response.json() return None except (httpx.ConnectError, httpx.TimeoutException): return None