from typing import Any import requests class BookStackClientRequestFailedError(ConnectionError): def __init__(self, status: int, error: str) -> None: super().__init__( "BookStack Client request failed with status {status}: {error}".format( status=status, error=error ) ) class BookStackApiClient: def __init__( self, base_url: str, token_id: str, token_secret: str, ) -> None: self.base_url = base_url self.token_id = token_id self.token_secret = token_secret def get(self, endpoint: str, params: dict[str, str]) -> dict[str, Any]: url: str = self._build_url(endpoint) headers = self._build_headers() response = requests.get(url, headers=headers, params=params) try: json = response.json() except Exception: json = {} if response.status_code >= 300: error = response.reason response_error = json.get("error", {}).get("message", "") if response_error: error = response_error raise BookStackClientRequestFailedError(response.status_code, error) return json def _build_headers(self) -> dict[str, str]: auth = "Token " + self.token_id + ":" + self.token_secret return { "Authorization": auth, "Accept": "application/json", } def _build_url(self, endpoint: str) -> str: return self.base_url.rstrip("/") + "/api/" + endpoint.lstrip("/") def build_app_url(self, endpoint: str) -> str: return self.base_url.rstrip("/") + "/" + endpoint.lstrip("/")