import asyncio from aiohttp import ClientConnectionError, ClientResponseError, ClientSession from apollo_utils.service.exceptions import APIError from collections import namedtuple from typing import Dict, Type async def make_request( session: ClientSession, url: str, method: str = "GET", params: Dict = None, headers: Dict = None, auth: Type[namedtuple] = None, body: Dict or None = None, data: Dict or None = None, error_cls: Type[APIError] = APIError, error_message: str = None, ): """Make http request, handle errors. :param session: Http client session. :param url: Request URL. :param method: HTTP method. :param params: Request params passed as a dict. :param headers: Headers. :param auth: Auth tuple. :param body: Request body. :param data: Request data. :param error_cls: Error class. :param error_message: Custom error message. """ result = None try: async with session.request( method, url, params=params, headers=headers, auth=auth, json=body, data=data, raise_for_status=False ) as resp: if resp.content and resp.content_type == "application/json": result = await resp.json() try: resp.raise_for_status() except ClientResponseError as e: raise error_cls( detail=error_message or e.message, headers=e.headers, original_status_code=e.status, original_response=result, ) except ClientConnectionError as e: raise error_cls(detail=e.strerror if hasattr(e, "strerror") else "Connection error") except asyncio.CancelledError: raise error_cls(detail="Request was cancelled") return result