import requests class AAndTAPIError(Exception): """Raised when the legacy PolyLAN AAndT API is unreachable or errors out.""" class AAndTClient: """Thin wrapper around the legacy PolyLAN site's per-AAndT JWT-bearer API.""" def __init__(self, base_url: str, token: str, /, *, timeout: int = 15) -> None: self.timeout = timeout self.base_url = base_url.rstrip("/") self.session = requests.Session() self.session.headers["Authorization"] = f"Bearer {token}" def get_members(self) -> list[dict]: return self._get("members")["members"] def get_matches(self) -> list[dict]: return self._get("matches")["matches"] def set_match_message( self, match_id: int, /, *, players: str | None = None, admin: str | None = None, msg_all: str | None = None, ) -> None: body = { key: value for key, value in { "players": players, "admin": admin, "all": msg_all, }.items() if value is not None } self._post(f"match/{match_id}/messages", body) def _get(self, path: str) -> dict: try: response = self.session.get( f"{self.base_url}/Plamingo/aandt/api/aandt/{path}", timeout=self.timeout ) response.raise_for_status() except requests.RequestException as exc: raise AAndTAPIError(f"Failed to reach AAndT API ({path}): {exc}") from exc return response.json() def _post(self, path: str, data: dict) -> dict: try: response = self.session.post( f"{self.base_url}/Plamingo/aandt/api/aandt/{path}", json=data, timeout=self.timeout, ) response.raise_for_status() except requests.RequestException as exc: raise AAndTAPIError(f"Failed to reach AAndT API ({path}): {exc}") from exc return response.json()