app/services/recipient_service.py:27:class ImportReport:
app/services/recipient_service.py:49:def is_valid_email(addr: str) -> bool:
app/services/recipient_service.py:59:def parse_txt(content: str) -> List[str]:
app/services/recipient_service.py:70:def parse_csv(content: str) -> tuple:
app/services/recipient_service.py:104:def validate_rows(records: List[dict], suppression: set, bounced: set,
app/services/recipient_service.py:145:def make_unsub_token() -> str:
app/services/message_builder.py:22:class HtmlValidationError(Exception):
app/services/message_builder.py:26:def build_mime_message(
app/services/message_builder.py:83:def validate_html(html: str) -> List[str]:
app/services/message_builder.py:104:def html_to_pdf(html: str) -> bytes:
app/services/message_builder.py:112:def sanitize_preview(html: str) -> str:
app/services/message_builder.py:124:def sanitize_html_for_email(html: str) -> str:
app/services/message_builder.py:129:def generate_attachment_filename(kind: str, invoice_number: str) -> str:
=== gmail_service ===
45:class GmailOauthError(Exception):
52:def resolve_client_config(config=None) -> dict:
81:def parse_client_json(content: bytes) -> dict:
103:def generate_state() -> str:
107:def build_authorization_url(client: dict, state: str) -> str:
121:def exchange_code_for_tokens(client: dict, code: str) -> dict:
139:def refresh_access_token(client: dict, refresh_token: str) -> dict:
152:def revoke_token(token: str) -> bool:
163:def get_userinfo(access_token: str) -> dict:
173:class GmailClient:
249:def build_gmail_client_from_account(account, oauth_token, client_config=None) -> GmailClient:
262:def resolve_client_config_for_account(account) -> dict:
