diff --git a/mail_intake/__init__.py b/mail_intake/__init__.py index f2edf2b..e46a183 100644 --- a/mail_intake/__init__.py +++ b/mail_intake/__init__.py @@ -9,7 +9,8 @@ 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 management +- 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 @@ -38,15 +39,18 @@ required by the selected provider (for example, Google APIs for Gmail). Basic Usage ---------------------------------------------------------------------- -Minimal Gmail ingestion example: +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", - token_path="token.pickle", + store=store, scopes=["https://www.googleapis.com/auth/gmail.readonly"], ) @@ -69,9 +73,11 @@ 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` + ``adapters.MailIntakeAdapter`` - Users MAY implement their own authentication providers by subclassing - `auth.MailIntakeAuthProvider` + ``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 @@ -86,6 +92,7 @@ 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 @@ -103,6 +110,7 @@ Design Guarantees - 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. @@ -112,6 +120,7 @@ shortcuts. from . import ingestion from . import adapters from . import auth +from . import credentials from . import models from . import config from . import exceptions @@ -120,6 +129,7 @@ __all__ = [ "ingestion", "adapters", "auth", + "credentials", "models", "config", "exceptions", diff --git a/mail_intake/credentials/__init__.py b/mail_intake/credentials/__init__.py index d0d65c1..934923b 100644 --- a/mail_intake/credentials/__init__.py +++ b/mail_intake/credentials/__init__.py @@ -1,8 +1,29 @@ """ +Credential persistence interfaces and implementations for Mail Intake. + +This package defines the abstractions and concrete implementations used +to persist authentication credentials across Mail Intake components. + +The credential persistence layer is intentionally decoupled from +authentication logic. Authentication providers are responsible for +credential acquisition, validation, and refresh, while implementations +within this package are responsible solely for storage and retrieval. + +The package provides: +- A generic ``CredentialStore`` abstraction defining the persistence contract +- Local filesystem–based storage for development and single-node use +- Distributed, Redis-backed storage for production and scaled deployments + +Credential lifecycle management, interpretation, and security policy +decisions remain the responsibility of authentication providers. +""" + from mail_intake.credentials.store import CredentialStore +from mail_intake.credentials.pickle import PickleCredentialStore +from mail_intake.credentials.redis import RedisCredentialStore -from google.oauth2.credentials import Credentials - -GoogleCredentialStore = CredentialStore[Credentials] - -""" \ No newline at end of file +__all__ = [ + "CredentialStore", + "PickleCredentialStore", + "RedisCredentialStore", +]