import logging from anydi import singleton from app.adapters.briteverify.bulk_client import BriteVerifyBulkClient from app.adapters.db import Database from app.adapters.db.emails.repository import EmailsRepository logger = logging.getLogger(__name__) @singleton class BriteVerifyEmailCheckerHandler: def __init__( self, repository: EmailsRepository, briteverify_client: BriteVerifyBulkClient, db: Database, verify_list_limit: int, reserved_tokens_count: int, env: str, chunk_size: int, validation_start_date: str, ) -> None: self.repository = repository self.briteverify_client = briteverify_client self.db = db self.verify_list_limit = verify_list_limit self.reserved_tokens_count = reserved_tokens_count self.env = env self.chunk_size = chunk_size self.validation_start_date = validation_start_date def handle(self) -> None: with self.db.session_factory(): self.process_unprocessed_validation_lists() self.create_new_validation_list() def process_unprocessed_validation_lists(self) -> None: logger.info("Processing unprocessed validation lists") unprocessed_list_ids = self.repository.get_unprocessed_verify_list_ids() if not unprocessed_list_ids: logger.info("No unprocessed validation lists found") return for unprocessed_list_id in unprocessed_list_ids: logger.info("Processing validation list with ID: %s", unprocessed_list_id) list_state = self.briteverify_client.get_validation_list_state( unprocessed_list_id ) if list_state != "complete": logger.info( "Validation list with ID %s is not completed yet, current state: %s. Skipping for now.", unprocessed_list_id, list_state, ) self.repository.update_briteverify_list_state( unprocessed_list_id, list_state, processed=False ) continue results = self.briteverify_client.get_validation_results( unprocessed_list_id ) self.repository.update_briteverify_results(unprocessed_list_id, results) self.repository.update_briteverify_list_state( unprocessed_list_id, list_state, processed=True ) logger.info( "Finished processing validation list with ID: %s", unprocessed_list_id ) def create_new_validation_list(self) -> None: logger.info("Creating new validation list") available_briteverify_credits = self.briteverify_client.get_available_credits() if available_briteverify_credits <= self.reserved_tokens_count: logger.warning( "No available BriteVerify credits, skipping validation list creation" ) # TODO: Add slack notification return logger.info("Available BriteVerify credits: %s", available_briteverify_credits) remaining = min(available_briteverify_credits, self.verify_list_limit) while remaining > 0: chunk = self.repository.get_unverified_emails( start_date=self.validation_start_date, limit=min(self.chunk_size, remaining), ) if not chunk: break validation_list = self.briteverify_client.create_validation_list(chunk) logger.info( "Created validation list with ID: %s for %d emails", validation_list.id, len(chunk), ) self.repository.create_briteverify_list(validation_list) self.repository.create_pending_briteverify_results( validation_list.id, chunk ) logger.info( "Saved validation list with ID: %s and pending results", validation_list.id, ) remaining -= len(chunk)