from __future__ import annotations import base64 from pathlib import Path import requests from app.config import Config class EmailConfigurationError(RuntimeError): pass def send_pdf_report( config: Config, to_email: str, subject: str, body: str, pdf_path: Path, ) -> dict[str, object]: if not config.smtp2go_api_key: raise EmailConfigurationError("SMTP2GO_API_KEY is not configured.") if not config.report_sender_email: raise EmailConfigurationError("REPORT_SENDER_EMAIL is not configured.") sender = config.report_sender_email if config.report_sender_name: sender = f"{config.report_sender_name} <{config.report_sender_email}>" payload = { "api_key": config.smtp2go_api_key, "sender": sender, "to": [to_email], "subject": subject, "text_body": body, "attachments": [ { "filename": pdf_path.name, "fileblob": base64.b64encode(pdf_path.read_bytes()).decode("ascii"), "mimetype": "application/pdf", } ], } response = requests.post( config.smtp2go_api_url, json=payload, timeout=config.smtp2go_timeout_seconds, ) response.raise_for_status() data = response.json() if data.get("data", {}).get("succeeded") == 0: failures = data.get("data", {}).get("failures") or [] raise RuntimeError(f"SMTP2GO did not send the report: {failures}") return data