"""Helpers for AIOGitHubAPI.""" import asyncio from typing import Optional import aiohttp from aiohttp.client_exceptions import ClientError import backoff from ..common.const import HTTP_STATUS_CODE_GOOD_LIST, HttpMethod, HttpStatusCode from ..common.exceptions import ( AIOGitHubAPIAuthenticationException, AIOGitHubAPIException, AIOGitHubAPINotModifiedException, AIOGitHubAPIRatelimitException, ) from ..objects.base import AIOGitHubAPIResponse def short_sha(sha: str) -> str: """Return the first 7 characters of the sha.""" return sha[0:7] def short_message(message: str) -> str: """Return the first line of a message""" return message.split("\n")[0] @backoff.on_exception( backoff.expo, (ClientError, asyncio.CancelledError, TimeoutError, KeyError), max_tries=5, logger=None, ) async def async_call_api( session: aiohttp.ClientSession, method: HttpMethod, url: str, headers: dict, params: Optional[dict] = None, data: dict or str or None = None, jsondata: bool = True, returnjson: bool = True, ) -> AIOGitHubAPIResponse: """Execute the API call.""" response = AIOGitHubAPIResponse() async with asyncio.timeout(20): if method == HttpMethod.GET: result = await session.get(url, params=params or {}, headers=headers) else: if jsondata: result = await session.post( url, params=params or {}, headers=headers, json=data or {}, ) else: result = await session.post( url, params=params or {}, headers=headers, data=data or "", ) response.status = result.status response.headers = result.headers if response.status == HttpStatusCode.RATELIMIT: raise AIOGitHubAPIRatelimitException("GitHub Ratelimit error") if response.status == HttpStatusCode.UNAUTHORIZED: raise AIOGitHubAPIAuthenticationException(HttpStatusCode.UNAUTHORIZED) if response.status == HttpStatusCode.NOT_MODIFIED: raise AIOGitHubAPINotModifiedException(f"Response from {url} was not modified.") if response.status not in HTTP_STATUS_CODE_GOOD_LIST: raise AIOGitHubAPIException( f"GitHub returned {HttpStatusCode(response.status)} for {url}" ) if returnjson: response.data = await result.json() else: response.data = await result.text() if isinstance(response.data, dict): if response.data.get("message"): if response.data["message"] == "Bad credentials": raise AIOGitHubAPIAuthenticationException("Access token is not valid!") raise AIOGitHubAPIException(response.data) return response