google styled doc

This commit is contained in:
2026-03-08 00:29:24 +05:30
parent 9f37af5761
commit 9f9e472ada
21 changed files with 593 additions and 358 deletions

View File

@@ -1,6 +1,10 @@
"""
Credential persistence interfaces and implementations for Mail Intake.
---
## Summary
This package defines the abstractions and concrete implementations used
to persist authentication credentials across Mail Intake components.
@@ -16,6 +20,16 @@ The package provides:
Credential lifecycle management, interpretation, and security policy
decisions remain the responsibility of authentication providers.
---
## Public API
CredentialStore
PickleCredentialStore
RedisCredentialStore
---
"""
from mail_intake.credentials.store import CredentialStore

View File

@@ -1,6 +1,10 @@
"""
Local filesystembased credential persistence for Mail Intake.
---
## Summary
This module provides a file-backed implementation of the
``CredentialStore`` abstraction using Python's ``pickle`` module.
@@ -29,13 +33,16 @@ class PickleCredentialStore(CredentialStore[T]):
filesystem. It is a simple implementation intended primarily for
development, testing, and single-process execution contexts.
This implementation:
- Stores credentials on the local filesystem
- Uses pickle for serialization and deserialization
- Does not provide encryption, locking, or concurrency guarantees
Notes:
**Guarantees:**
Credential lifecycle management, validation, and refresh logic are
explicitly out of scope for this class.
- Stores credentials on the local filesystem
- Uses pickle for serialization and deserialization
- Does not provide encryption, locking, or concurrency guarantees
**Constraints:**
- Credential lifecycle management, validation, and refresh logic are explicitly out of scope for this class
"""
def __init__(self, path: str):
@@ -43,7 +50,7 @@ class PickleCredentialStore(CredentialStore[T]):
Initialize a pickle-backed credential store.
Args:
path:
path (str):
Filesystem path where credentials will be stored.
The file will be created or overwritten as needed.
"""
@@ -53,15 +60,16 @@ class PickleCredentialStore(CredentialStore[T]):
"""
Load credentials from the local filesystem.
If the credential file does not exist or cannot be successfully
deserialized, this method returns ``None``.
The store does not attempt to validate or interpret the returned
credentials.
Returns:
An instance of type ``T`` if credentials are present and
successfully deserialized; otherwise ``None``.
Optional[T]:
An instance of type ``T`` if credentials are present and
successfully deserialized; otherwise ``None``.
Notes:
**Guarantees:**
- If the credential file does not exist or cannot be successfully deserialized, this method returns ``None``
- The store does not attempt to validate or interpret the returned credentials
"""
try:
with open(self.path, "rb") as fh:
@@ -73,12 +81,14 @@ class PickleCredentialStore(CredentialStore[T]):
"""
Persist credentials to the local filesystem.
Any previously stored credentials at the configured path are
overwritten.
Args:
credentials:
credentials (T):
The credential object to persist.
Notes:
**Responsibilities:**
- Any previously stored credentials at the configured path are overwritten
"""
with open(self.path, "wb") as fh:
pickle.dump(credentials, fh)
@@ -87,8 +97,10 @@ class PickleCredentialStore(CredentialStore[T]):
"""
Remove persisted credentials from the local filesystem.
This method deletes the credential file if it exists and should
be treated as an idempotent operation.
Notes:
**Lifecycle:**
- This method deletes the credential file if it exists and should be treated as an idempotent operation
"""
import os

View File

@@ -1,6 +1,10 @@
"""
Redis-backed credential persistence for Mail Intake.
---
## Summary
This module provides a Redis-based implementation of the
``CredentialStore`` abstraction, enabling credential persistence
across distributed and horizontally scaled deployments.
@@ -37,14 +41,16 @@ class RedisCredentialStore(CredentialStore[T]):
distributed and horizontally scaled deployments where credentials
must be shared across multiple processes or nodes.
The store is intentionally generic and delegates all serialization
concerns to caller-provided functions. This avoids unsafe mechanisms
such as pickle and allows credential formats to be explicitly
controlled and audited.
Notes:
**Responsibilities:**
This class is responsible only for persistence and retrieval.
It does not interpret, validate, refresh, or otherwise manage
the lifecycle of the credentials being stored.
- This class is responsible only for persistence and retrieval
- It does not interpret, validate, refresh, or otherwise manage the lifecycle of the credentials being stored
**Guarantees:**
- The store is intentionally generic and delegates all serialization concerns to caller-provided functions
- This avoids unsafe mechanisms such as pickle and allows credential formats to be explicitly controlled and audited
"""
def __init__(
@@ -59,31 +65,20 @@ class RedisCredentialStore(CredentialStore[T]):
Initialize a Redis-backed credential store.
Args:
redis_client:
An initialized Redis client instance (for example,
``redis.Redis`` or a compatible interface) used to
communicate with the Redis server.
redis_client (Any):
An initialized Redis client instance (for example, ``redis.Redis`` or a compatible interface) used to communicate with the Redis server.
key:
The Redis key under which credentials are stored.
Callers are responsible for applying appropriate
namespacing to avoid collisions.
key (str):
The Redis key under which credentials are stored. Callers are responsible for applying appropriate namespacing to avoid collisions.
serialize:
A callable that converts a credential object of type
``T`` into a ``bytes`` representation suitable for
storage in Redis.
serialize (Callable[[T], bytes]):
A callable that converts a credential object of type ``T`` into a ``bytes`` representation suitable for storage in Redis.
deserialize:
A callable that converts a ``bytes`` payload retrieved
from Redis back into a credential object of type ``T``.
deserialize (Callable[[bytes], T]):
A callable that converts a ``bytes`` payload retrieved from Redis back into a credential object of type ``T``.
ttl_seconds:
Optional time-to-live (TTL) for the stored credentials,
expressed in seconds. When provided, Redis will
automatically expire the stored credentials after the
specified duration. If ``None``, credentials are stored
without an expiration.
ttl_seconds (Optional[int]):
Optional time-to-live (TTL) for the stored credentials, expressed in seconds. When provided, Redis will automatically expire the stored credentials after the specified duration. If ``None``, credentials are stored without an expiration.
"""
self.redis = redis_client
self.key = key
@@ -95,16 +90,16 @@ class RedisCredentialStore(CredentialStore[T]):
"""
Load credentials from Redis.
If no value exists for the configured key, or if the stored
payload cannot be successfully deserialized, this method
returns ``None``.
The store does not attempt to validate the returned credentials
or determine whether they are expired or otherwise usable.
Returns:
An instance of type ``T`` if credentials are present and
successfully deserialized; otherwise ``None``.
Optional[T]:
An instance of type ``T`` if credentials are present and
successfully deserialized; otherwise ``None``.
Notes:
**Guarantees:**
- If no value exists for the configured key, or if the stored payload cannot be successfully deserialized, this method returns ``None``
- The store does not attempt to validate the returned credentials or determine whether they are expired or otherwise usable
"""
raw = self.redis.get(self.key)
if not raw:
@@ -118,13 +113,15 @@ class RedisCredentialStore(CredentialStore[T]):
"""
Persist credentials to Redis.
Any previously stored credentials under the same key are
overwritten. If a TTL is configured, the credentials will
expire automatically after the specified duration.
Args:
credentials:
credentials (T):
The credential object to persist.
Notes:
**Responsibilities:**
- Any previously stored credentials under the same key are overwritten
- If a TTL is configured, the credentials will expire automatically after the specified duration
"""
payload = self.serialize(credentials)
if self.ttl_seconds:
@@ -136,7 +133,10 @@ class RedisCredentialStore(CredentialStore[T]):
"""
Remove stored credentials from Redis.
This operation deletes the configured Redis key if it exists.
Implementations should treat this method as idempotent.
Notes:
**Lifecycle:**
- This operation deletes the configured Redis key if it exists
- Implementations should treat this method as idempotent
"""
self.redis.delete(self.key)

View File

@@ -1,6 +1,10 @@
"""
Credential persistence abstractions for Mail Intake.
---
## Summary
This module defines the generic persistence contract used to store and
retrieve authentication credentials across Mail Intake components.
@@ -29,16 +33,18 @@ class CredentialStore(ABC, Generic[T]):
Abstract base class defining a generic persistence interface for
authentication credentials.
This interface separates *credential lifecycle management* from
*credential storage mechanics*. Implementations are responsible
only for persistence concerns, while authentication providers
retain full control over credential creation, validation, refresh,
and revocation logic.
Notes:
**Responsibilities:**
The store is intentionally agnostic to:
- The concrete credential type being stored
- The serialization format used to persist credentials
- The underlying storage backend or durability guarantees
- Provide persistent storage separating life-cycle management from storage mechanics
- Keep implementation focused only on persistence
**Constraints:**
- The store is intentionally agnostic to:
- The concrete credential type being stored
- The serialization format used to persist credentials
- The underlying storage backend or durability guarantees
"""
@abstractmethod
@@ -46,16 +52,16 @@ class CredentialStore(ABC, Generic[T]):
"""
Load previously persisted credentials.
Implementations should return ``None`` when no credentials are
present or when stored credentials cannot be successfully
decoded or deserialized.
The store must not attempt to validate, refresh, or otherwise
interpret the returned credentials.
Returns:
An instance of type ``T`` if credentials are available and
loadable; otherwise ``None``.
Optional[T]:
An instance of type ``T`` if credentials are available and
loadable; otherwise ``None``.
Notes:
**Guarantees:**
- Implementations should return ``None`` when no credentials are present or when stored credentials cannot be successfully decoded or deserialized
- The store must not attempt to validate, refresh, or otherwise interpret the returned credentials
"""
@abstractmethod
@@ -63,18 +69,20 @@ class CredentialStore(ABC, Generic[T]):
"""
Persist credentials to the underlying storage backend.
This method is invoked when credentials are newly obtained or
have been refreshed and are known to be valid at the time of
persistence.
Implementations are responsible for:
- Ensuring durability appropriate to the deployment context
- Applying encryption or access controls where required
- Overwriting any previously stored credentials
Args:
credentials:
credentials (T):
The credential object to persist.
Notes:
**Lifecycle:**
- This method is invoked when credentials are newly obtained or have been refreshed and are known to be valid at the time of persistence
**Responsibilities:**
- Ensuring durability appropriate to the deployment context
- Applying encryption or access controls where required
- Overwriting any previously stored credentials
"""
@abstractmethod
@@ -82,9 +90,13 @@ class CredentialStore(ABC, Generic[T]):
"""
Remove any persisted credentials from the store.
This method is called when credentials are known to be invalid,
revoked, corrupted, or otherwise unusable, and must ensure that
no stale authentication material remains accessible.
Notes:
**Lifecycle:**
Implementations should treat this operation as idempotent.
- This method is called when credentials are known to be invalid, revoked, corrupted, or otherwise unusable
- Must ensure that no stale authentication material remains accessible
**Guarantees:**
- Implementations should treat this operation as idempotent
"""