Source code for python_awair.client

"""Wrapper class to query the Awair API."""

from typing import Any, Dict, NoReturn

from aiohttp import ClientResponse, ClientSession

from python_awair.auth import AwairAuth
from python_awair.exceptions import (
    AuthError,
    AwairError,
    NotFoundError,
    QueryError,
    RatelimitError,
)


[docs]class AwairClient: """Python asyncio client for the Awair GraphQL API.""" def __init__(self, authenticator: AwairAuth, session: ClientSession,) -> None: """Initialize an AwairClient with sensible defaults.""" self.__authenticator = authenticator self.__session = session
[docs] async def query(self, url: str) -> Any: """Query the Awair api, and handle errors.""" headers = await self.__headers() async with self.__session.get(url, headers=headers) as resp: if resp.status != 200: self.__handle_non_200_error(resp) json = await resp.json() self.__check_errors_array(json) return json
async def __headers(self) -> Dict[str, str]: """Return headers to set on the API request.""" token = await self.__authenticator.get_bearer_token() return { "Authorization": f"Bearer {token}", "Content-Type": "application/json", } @staticmethod def __check_errors_array(json: Dict[Any, Any]) -> None: """Check for an "errors" array and process it. Holdover from the GraphQL API, unclear if we could still get messages like this. """ if "errors" in json: messages = [] for error in json["errors"]: if "Too many requests" in error["message"]: raise RatelimitError() messages.append(error.get("message", "Unknown error")) if messages: raise AwairError(", ".join(messages)) @staticmethod def __handle_non_200_error(resp: ClientResponse) -> NoReturn: if resp.status == 400: raise QueryError() if resp.status in (401, 403): raise AuthError() if resp.status == 404: raise NotFoundError() if resp.status == 429: raise RatelimitError() raise AwairError()