from collections.abc import AsyncIterable from aioboto3.session import Session from dishka import Provider, Scope, provide from httpx import AsyncClient, Timeout from sqlalchemy.ext.asyncio import AsyncEngine, AsyncSession, create_async_engine from template_project.adapters.ml_api_gateway import MlApiGateway from template_project.adapters.s3_storage import AioBoto3ClientLike from template_project.web_api.configuration import DatabaseConfiguration, MlApiConfiguration, S3Config class ConnectionProvider(Provider): @provide(scope=Scope.APP) async def engine(self, configuration: DatabaseConfiguration) -> AsyncIterable[AsyncEngine]: engine = create_async_engine(configuration.url.get_value()) yield engine await engine.dispose() @provide(scope=Scope.REQUEST) async def async_session(self, engine: AsyncEngine) -> AsyncIterable[AsyncSession]: session = AsyncSession( bind=engine, expire_on_commit=False, ) async with session: yield session @provide(scope=Scope.APP) async def s3_client(self, config: S3Config) -> AsyncIterable[AioBoto3ClientLike]: session = Session() # type: ignore[no-untyped-call] async with session.client( "s3", endpoint_url=config.endpoint_url, aws_access_key_id=config.access_key, aws_secret_access_key=config.secret_key, ) as s3_client: yield s3_client @provide(scope=Scope.APP) async def ml_api_gateway(self, config: MlApiConfiguration) -> AsyncIterable[MlApiGateway]: timeout = Timeout(30.0, read=30.0) async with AsyncClient(base_url=config.url, timeout=timeout) as client: yield MlApiGateway(client)