import asyncio
import io
from typing import Optional, Union
import aiohttp
from yarl import URL
from . import __version__
from .enums import RequestTypes
from .errors import *
[docs]class BaseHTTP:
"""The base class for making http requests
:param api_token: The fluxpoint api token https://fluxpoint.dev/api/access
:type api_token: str
"""
__slots__ = ["api_token"]
def __init__(self, api_token: str) -> None:
self.api_token: str = api_token
self.__user_agent: str = f"fluxpoint/{__version__}"
[docs] async def request(
self,
method: RequestTypes,
endpoint: str,
json: Optional[dict] = None,
headers: Optional[dict] = None,
_base_url: Optional[Union[str, URL]] = 'https://api.fluxpoint.dev/',
retry: bool = True,
return_json: bool = True,
return_bytes: bool = False,
retry_times: int = 1
) -> Union[aiohttp.ClientResponse, dict, io.IOBase]:
"""Makes an API request
:raises RateLimited: When the 429 response is returned
:raises WrongReturnType: When the :exc:`UnicodeDecodeError` is raised
:raises ParameterError: When the 400 response is returned
:raises Unauthorised: When the 401 response is returned
:raises ApiError: When the 500 response is returned
:raises HttpException: For the other and generall http exceptions
:return: Bytes data for the image
:rtype: Union[aiohttp.ClientResponse, dict, io.IOBase]
"""
if json is None:
json = {}
__base_url: str = _base_url if _base_url.endswith(
'/') else _base_url.strip() + '/'
headers = {} if not headers else headers
headers["Authorization"] = self.api_token
headers["User-Agent"] = self.__user_agent
async with aiohttp.ClientSession() as session:
async with session.request(str(method.name).upper(), f'{__base_url}{str(endpoint)}', headers=headers, json=json) as response:
if response.status == 429:
if not retry:
raise RateLimited("Too many requests, try again later")
await asyncio.sleep(response.headers.get('Retry-After'))
return await self.request(method, endpoint, json, headers, retry=retry_times <= 10, retry_times=retry_times+1)
try:
result = await response.json(content_type="application/json") if return_json else (await response.read()if return_bytes else response)
if response.status == 200:
return result
result = await response.json(content_type="application/json") if not isinstance(result, dict) else result
except UnicodeDecodeError:
raise WrongReturnType("Wrong return type is given")
if response.status == 400:
raise ParameterError(result.get("message"))
if response.status == 401:
raise Unauthorised(result.get("message"))
if response.status == 500:
raise ApiError(result.get("message"))
raise HttpException(response.status, result)