""" Mail Intake — provider-agnostic, read-only email ingestion framework. Mail Intake is a **contract-first library** designed to ingest, parse, and normalize email data from external providers (such as Gmail) into clean, provider-agnostic domain models. The library is intentionally structured around clear layers, each exposed as a first-class module at the package root: - adapters: provider-specific access (e.g. Gmail) - auth: authentication providers and credential lifecycle management - credentials: credential persistence abstractions and implementations - parsers: extraction and normalization of message content - ingestion: orchestration and high-level ingestion workflows - models: canonical, provider-agnostic data representations - config: explicit global configuration - exceptions: library-defined error hierarchy The package root acts as a **namespace**, not a facade. Consumers are expected to import functionality explicitly from the appropriate module. ---------------------------------------------------------------------- Installation ---------------------------------------------------------------------- Install using pip: pip install mail-intake Or with Poetry: poetry add mail-intake Mail Intake is pure Python and has no runtime dependencies beyond those required by the selected provider (for example, Google APIs for Gmail). ---------------------------------------------------------------------- Basic Usage ---------------------------------------------------------------------- Minimal Gmail ingestion example (local development): from mail_intake.ingestion import MailIntakeReader from mail_intake.adapters import MailIntakeGmailAdapter from mail_intake.auth import MailIntakeGoogleAuth from mail_intake.credentials import PickleCredentialStore store = PickleCredentialStore(path="token.pickle") auth = MailIntakeGoogleAuth( credentials_path="credentials.json", store=store, scopes=["https://www.googleapis.com/auth/gmail.readonly"], ) adapter = MailIntakeGmailAdapter(auth_provider=auth) reader = MailIntakeReader(adapter) for message in reader.iter_messages("from:recruiter@example.com"): print(message.subject, message.from_email) Iterating over threads: for thread in reader.iter_threads("subject:Interview"): print(thread.normalized_subject, len(thread.messages)) ---------------------------------------------------------------------- Extensibility Model ---------------------------------------------------------------------- Mail Intake is designed to be extensible via **public contracts** exposed through its modules: - Users MAY implement their own mail adapters by subclassing ``adapters.MailIntakeAdapter`` - Users MAY implement their own authentication providers by subclassing ``auth.MailIntakeAuthProvider[T]`` - Users MAY implement their own credential persistence layers by implementing ``credentials.CredentialStore[T]`` Users SHOULD NOT subclass built-in adapter implementations. Built-in adapters (such as Gmail) are reference implementations and may change internally without notice. ---------------------------------------------------------------------- Public API Surface ---------------------------------------------------------------------- The supported public API consists of the following top-level modules: - mail_intake.ingestion - mail_intake.adapters - mail_intake.auth - mail_intake.credentials - mail_intake.parsers - mail_intake.models - mail_intake.config - mail_intake.exceptions Classes and functions should be imported explicitly from these modules. No individual symbols are re-exported at the package root. ---------------------------------------------------------------------- Design Guarantees ---------------------------------------------------------------------- - Read-only access: no mutation of provider state - Provider-agnostic domain models - Explicit configuration and dependency injection - No implicit global state or environment reads - Deterministic, testable behavior - Distributed-safe authentication design Mail Intake favors correctness, clarity, and explicitness over convenience shortcuts. """ from . import ingestion from . import adapters from . import auth from . import credentials from . import models from . import config from . import exceptions __all__ = [ "ingestion", "adapters", "auth", "credentials", "models", "config", "exceptions", ]