from collections.abc import Iterator import sqlalchemy.pool from anydi import Container, Module, Provider, provider from fansifter_common.utils.functional import lazy_proxy from jinja2sql import Jinja2SQL from app.adapters.briteverify.bulk_client import BriteVerifyBulkClient from app.adapters.db import Database from app.adapters.db.emails.repository import EmailsRepository from app.config import Settings, settings from app.handler import BriteVerifyEmailCheckerHandler class AppModule(Module): @provider(scope="singleton") def jinja2sql(self, settings: Settings) -> Jinja2SQL: jinja2sql = Jinja2SQL(searchpath=settings.jinja2sql_template_searchpath) jinja2sql.env.globals.update({"settings": settings}) # type: ignore return jinja2sql @provider(scope="singleton") def db(self, settings: Settings, jinja2sql: Jinja2SQL) -> Iterator[Database]: with Database( url=settings.snowflake_url, engine_args={ "echo": settings.snowflake_echo, "poolclass": sqlalchemy.pool.QueuePool, "pool_size": settings.snowflake_pool_size, "max_overflow": settings.snowflake_pool_max_overflow, "pool_recycle": settings.snowflake_pool_recycle, "pool_pre_ping": settings.snowflake_pool_pre_ping, "pool_reset_on_return": settings.snowflake_pool_reset_on_return, "connect_args": settings.snowflake_connect_args, }, jinja2sql=jinja2sql, ) as db: yield db @provider(scope="singleton") def briteverify_client(self, settings: Settings) -> BriteVerifyBulkClient: return BriteVerifyBulkClient(api_key=settings.briteverify_api_key) @provider(scope="singleton") def handler( self, repository: EmailsRepository, briteverify_client: BriteVerifyBulkClient, db: Database, settings: Settings, ) -> BriteVerifyEmailCheckerHandler: return BriteVerifyEmailCheckerHandler( repository=repository, briteverify_client=briteverify_client, db=db, verify_list_limit=settings.verify_list_limit, reserved_tokens_count=settings.briteverify_reserved_tokens_count, env=settings.environment, chunk_size=settings.briteverify_chunk_size, validation_start_date=settings.validation_start_date, ) def make_container() -> Container: # Configure DI container return Container( providers=[ Provider(Settings, factory=lambda: settings, scope="singleton"), ], modules=[AppModule], ) container = lazy_proxy(make_container)