from __future__ import annotations import json from typing import Any, Dict, Optional from .HTTP import HTTPClient class ApiError(Exception): """Base exception for API errors.""" pass class API: """Base class for API clients using the internal HTTPClient.""" def __init__(self, base_url: str, timeout: float = 10.0) -> None: self.base_url = str(base_url or "").rstrip("/") self.timeout = float(timeout) def _get_json( self, path: str, params: Optional[Dict[str, Any]] = None, headers: Optional[Dict[str, str]] = None, ) -> Dict[str, Any]: url = f"{self.base_url}/{str(path or '').lstrip('/')}" try: with HTTPClient(timeout=self.timeout, headers=headers) as client: response = client.get(url, params=params, allow_redirects=True) response.raise_for_status() return response.json() except Exception as exc: raise ApiError(f"API request failed for {url}: {exc}") from exc def _post_json( self, path: str, json_data: Optional[Dict[str, Any]] = None, params: Optional[Dict[str, Any]] = None, headers: Optional[Dict[str, str]] = None, ) -> Dict[str, Any]: url = f"{self.base_url}/{str(path or '').lstrip('/')}" try: with HTTPClient(timeout=self.timeout, headers=headers) as client: response = client.post(url, json=json_data, params=params, allow_redirects=True) response.raise_for_status() return response.json() except Exception as exc: raise ApiError(f"API request failed for {url}: {exc}") from exc