class ImportReport: def __init__(self): self.rows_seen = 0 self.valid: List[dict] = [] self.invalid: List[dict] = [] self.duplicates: List[dict] = [] self.suppressed: List[dict] = [] self.bounced: List[dict] = [] self.errors: List[str] = [] def summary(self) -> dict: return { "total_imported": self.rows_seen, "valid_recipients": len(self.valid), "invalid_recipients": len(self.invalid), "duplicate_recipients": len(self.duplicates), "suppressed_recipients": len(self.suppressed), "bounced_recipients": len(self.bounced), "errors": self.errors, } def is_valid_email(addr: str) -> bool: if not addr or len(addr) > 320: return False try: v = validate_email(addr, check_deliverability=False) return True except EmailNotValidError: return EMAIL_RE.match(addr) is not None def parse_txt(content: str) -> List[str]: """One email per line (optionally 'email, First, Last' comma-separated)."""