pyhOn/pyhon/connection/handler/base.py

79 lines
2.5 KiB
Python
Raw Normal View History

2023-04-15 12:22:04 +00:00
import logging
from collections.abc import AsyncIterator
2023-07-12 17:36:32 +00:00
from contextlib import asynccontextmanager, _AsyncGeneratorContextManager
2023-06-28 17:02:11 +00:00
from types import TracebackType
2023-07-12 17:36:32 +00:00
from typing import Optional, Dict, Type, Any, Callable, Coroutine, AsyncGenerator
2023-04-15 12:22:04 +00:00
import aiohttp
from typing_extensions import Self
2023-06-28 18:25:52 +00:00
from yarl import URL
2023-04-15 12:22:04 +00:00
from pyhon import const, exceptions
2023-06-28 17:02:11 +00:00
from pyhon.typedefs import Callback
2023-04-15 12:22:04 +00:00
_LOGGER = logging.getLogger(__name__)
class ConnectionHandler:
2023-06-28 17:02:11 +00:00
_HEADERS: Dict[str, str] = {
2023-04-15 12:22:04 +00:00
"user-agent": const.USER_AGENT,
"Content-Type": "application/json",
}
def __init__(self, session: Optional[aiohttp.ClientSession] = None) -> None:
self._create_session: bool = session is None
self._session: Optional[aiohttp.ClientSession] = session
async def __aenter__(self) -> Self:
return await self.create()
2023-06-28 17:02:11 +00:00
async def __aexit__(
self,
exc_type: Optional[Type[BaseException]],
exc: Optional[BaseException],
traceback: Optional[TracebackType],
) -> None:
2023-04-15 12:22:04 +00:00
await self.close()
2023-06-28 17:02:11 +00:00
@property
def session(self) -> aiohttp.ClientSession:
if self._session is None:
raise exceptions.NoSessionException
return self._session
2023-04-15 12:22:04 +00:00
async def create(self) -> Self:
if self._create_session:
self._session = aiohttp.ClientSession()
return self
@asynccontextmanager
2023-07-12 17:36:32 +00:00
async def _intercept(
2023-06-28 18:25:52 +00:00
self, method: Callback, url: str | URL, *args: Any, **kwargs: Dict[str, Any]
2023-06-28 17:02:11 +00:00
) -> AsyncIterator[aiohttp.ClientResponse]:
2023-07-12 17:36:32 +00:00
async with method(url, *args, **kwargs) as response:
yield response
2023-04-15 12:22:04 +00:00
@asynccontextmanager
2023-06-28 17:02:11 +00:00
async def get(
self, *args: Any, **kwargs: Any
) -> AsyncIterator[aiohttp.ClientResponse]:
2023-04-15 12:22:04 +00:00
if self._session is None:
raise exceptions.NoSessionException()
2023-04-15 13:55:22 +00:00
response: aiohttp.ClientResponse
2023-06-28 17:02:11 +00:00
async with self._intercept(self._session.get, *args, **kwargs) as response: # type: ignore[arg-type]
2023-04-15 12:22:04 +00:00
yield response
@asynccontextmanager
2023-06-28 17:02:11 +00:00
async def post(
self, *args: Any, **kwargs: Any
) -> AsyncIterator[aiohttp.ClientResponse]:
2023-04-15 12:22:04 +00:00
if self._session is None:
raise exceptions.NoSessionException()
2023-04-15 13:55:22 +00:00
response: aiohttp.ClientResponse
2023-06-28 17:02:11 +00:00
async with self._intercept(self._session.post, *args, **kwargs) as response: # type: ignore[arg-type]
2023-04-15 12:22:04 +00:00
yield response
async def close(self) -> None:
if self._create_session and self._session is not None:
await self._session.close()