"""Small async client for the internal AuthZ service.""" from __future__ import annotations from typing import Any import httpx class AuthzClient: def __init__(self, base_url: str, timeout_seconds: int = 10) -> None: self.base_url = base_url.rstrip("/") self.timeout_seconds = timeout_seconds async def _request(self, method: str, path: str, *, json_body: dict[str, Any] | None = None) -> Any: async with httpx.AsyncClient( timeout=self.timeout_seconds, follow_redirects=True, trust_env=False, ) as client: response = await client.request(method, f"{self.base_url}{path}", json=json_body) response.raise_for_status() if not response.content: return None return response.json() async def issue_token( self, *, client_id: str, client_secret: str, audience: str, scopes: list[str], ) -> dict[str, Any]: data = await self._request( "POST", "/oauth/token", json_body={ "grant_type": "client_credentials", "client_id": client_id, "client_secret": client_secret, "aud": audience, "scopes": list(scopes), }, ) return data if isinstance(data, dict) else {} async def get_permissions(self, backend_id: str) -> dict[str, Any]: data = await self._request("GET", f"/backends/{backend_id}/permissions") return data if isinstance(data, dict) else {}