from typing import Annotated from anydi import Container, Module, Provider, provider from fansifter_common import context from fansifter_common.adapters.aws.secretsmanager import SecretsManager from fansifter_common.constants import PROD_ENVIRONMENT, QA_ENVIRONMENT from fansifter_common.m2m_token import M2MTokenManager from fansifter_common.utils.functional import lazy_proxy from owsclient import OwsClient from sendgrid.helpers.eventwebhook import ( # type: ignore[reportMissingTypeStubs] EventWebhook, ) from app.adapters.aws.s3 import S3Client from app.adapters.ows_preference_center import OwsPreferenceCenterClient from app.auth import Auth from app.config import Settings, settings from app.handlers import SendgridEventHandler FailedEventsS3Bucket = Annotated[str, "Failed events S3 bucket"] SendgridValidators = dict[str, EventWebhook] class AppModule(Module): @provider(scope="singleton") def secrets_manager(self, settings: Settings) -> SecretsManager: return SecretsManager(region_name=settings.aws_region_name) @provider(scope="singleton") def m2m_token_manager( self, settings: Settings, secrets_manager: SecretsManager ) -> M2MTokenManager: return M2MTokenManager( secrets_manager=secrets_manager, secret_name_key=settings.m2m_token_secret_key_name, secret_expire_name_key=settings.m2m_token_secret_expiry_key_name, ) @provider(scope="singleton") def ows_client( self, settings: Settings, m2m_token_manager: M2MTokenManager ) -> OwsClient: return OwsClient( environment=settings.environment, service_name=settings.service_name, m2m_token_manager=m2m_token_manager if settings.environment in [QA_ENVIRONMENT, PROD_ENVIRONMENT] else None, correlation_id_getter=context.get_correlation_id, request_context_getter=context.get_request_context, ) @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 settings.failed_events_s3_bucket @provider(scope="singleton") def sendgrid_validators(self, settings: Settings) -> SendgridValidators: validators: SendgridValidators = {} 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 handler( self, auth: Auth, s3_client: S3Client, ows_preference_center_client: OwsPreferenceCenterClient, failed_events_s3_bucket: FailedEventsS3Bucket, ) -> SendgridEventHandler: return SendgridEventHandler( auth=auth, s3_client=s3_client, ows_preference_center_client=ows_preference_center_client, failed_events_s3_bucket=failed_events_s3_bucket, ) def make_container() -> Container: return Container( providers=[ Provider(Settings, factory=lambda: settings, scope="singleton"), ], modules=[AppModule], ) container = lazy_proxy(make_container)