from typing import Annotated from anydi import Container, Module, Provider, provider from confluent_kafka import Producer from fansifter_common.utils.functional import lazy_proxy from sendgrid.helpers.eventwebhook import EventWebhook from app.auth import Auth from app.config import Settings, settings from app.connectors.aws.s3 import S3Client from app.handlers import SendgridEventHandler FailedEventsS3Bucket = Annotated[str, "Failed events S3 bucket"] SendgridValidators = dict[str, EventWebhook] class AppModule(Module): @provider(scope="singleton") def kafka_producer(self, settings: Settings) -> Producer: producer = Producer( { "bootstrap.servers": settings.kafka_bootstrap_servers, "security.protocol": "ssl" if settings.kafka_use_ssl else "plaintext", } ) return producer @provider(scope="singleton") def sendgrid_validators(self, settings: Settings) -> SendgridValidators: validators = {} for subuser, key in settings.sendgrid_public_keys.items(): validators[subuser] = EventWebhook(key) return validators @provider(scope="singleton") def auth(self, sendgrid_validators: SendgridValidators) -> Auth: return Auth(sendgrid_validators=sendgrid_validators) @provider(scope="singleton") def s3_client(self, settings: Settings) -> S3Client: client: S3Client = S3Client(region_name=settings.aws_region_name) return client @provider(scope="singleton") def failed_events_s3_bucket(self, settings: Settings) -> FailedEventsS3Bucket: return FailedEventsS3Bucket(settings.failed_events_s3_bucket) @provider(scope="singleton") def handler( self, settings: Settings, auth: Auth, kafka_producer: Producer, s3_client: S3Client, failed_events_s3_bucket: FailedEventsS3Bucket, ) -> SendgridEventHandler: return SendgridEventHandler( auth=auth, kafka_producer=kafka_producer, kafka_sendgrid_events_topic=settings.kafka_sendgrid_events_topic, s3_client=s3_client, failed_events_s3_bucket=failed_events_s3_bucket, ) def make_container() -> Container: # Configure DI container return Container( providers=[ Provider(Settings, factory=lambda: settings, scope="singleton"), ], modules=[AppModule], ) container = lazy_proxy(make_container)