fix: annotate redis_client param and formalize Args in RedisCredentialStore.__init__; refresh MCP docs

This commit is contained in:
2026-09-14 00:05:34 +05:30
parent 085fe5e03e
commit 089aad24c3
4 changed files with 47 additions and 39 deletions

View File

@@ -247,6 +247,13 @@
"signature": "<bound method Alias.signature of Alias('Callable', 'collections.abc.Callable')>",
"docstring": null
},
"Any": {
"name": "Any",
"kind": "alias",
"path": "mail_intake.credentials.redis.Any",
"signature": "<bound method Alias.signature of Alias('Any', 'typing.Any')>",
"docstring": null
},
"TypeVar": {
"name": "TypeVar",
"kind": "alias",
@@ -295,7 +302,7 @@
"name": "RedisCredentialStore",
"kind": "class",
"path": "mail_intake.credentials.redis.RedisCredentialStore",
"signature": "<bound method Class.signature of Class('RedisCredentialStore', 35, 137)>",
"signature": "<bound method Class.signature of Class('RedisCredentialStore', 35, 145)>",
"docstring": "Redis-backed implementation of `CredentialStore`.\n\nThis store persists credentials in Redis and is suitable for\ndistributed and horizontally scaled deployments where credentials\nmust be shared across multiple processes or nodes.\n\nNotes:\n **Responsibilities:**\n\n - This class is responsible only for persistence and retrieval.\n - It does not interpret, validate, refresh, or otherwise manage the\n lifecycle of the credentials being stored.\n\n **Guarantees:**\n\n - The store is intentionally generic and delegates all serialization\n concerns to caller-provided functions.\n - This avoids unsafe mechanisms such as `pickle` and allows\n credential formats to be explicitly controlled and audited.",
"members": {
"redis": {
@@ -337,31 +344,24 @@
"name": "load",
"kind": "function",
"path": "mail_intake.credentials.redis.RedisCredentialStore.load",
"signature": "<bound method Function.signature of Function('load', 80, 105)>",
"signature": "<bound method Function.signature of Function('load', 88, 113)>",
"docstring": "Load credentials from Redis.\n\nReturns:\n T | None:\n An instance of type `T` if credentials are present and\n successfully deserialized; otherwise `None`.\n\nNotes:\n **Guarantees:**\n\n - If no value exists for the configured key, or if the stored\n payload cannot be successfully deserialized, this method\n returns `None`.\n - The store does not attempt to validate the returned\n credentials or determine whether they are expired or\n otherwise usable."
},
"save": {
"name": "save",
"kind": "function",
"path": "mail_intake.credentials.redis.RedisCredentialStore.save",
"signature": "<bound method Function.signature of Function('save', 107, 125)>",
"signature": "<bound method Function.signature of Function('save', 115, 133)>",
"docstring": "Persist credentials to Redis.\n\nArgs:\n credentials (T):\n The credential object to persist.\n\nNotes:\n **Responsibilities:**\n\n - Any previously stored credentials under the same key are overwritten\n - If a TTL is configured, the credentials will expire automatically after the specified duration"
},
"clear": {
"name": "clear",
"kind": "function",
"path": "mail_intake.credentials.redis.RedisCredentialStore.clear",
"signature": "<bound method Function.signature of Function('clear', 127, 137)>",
"signature": "<bound method Function.signature of Function('clear', 135, 145)>",
"docstring": "Remove stored credentials from Redis.\n\nNotes:\n **Lifecycle:**\n\n - This operation deletes the configured Redis key if it exists\n - Implementations should treat this method as idempotent"
}
}
},
"Any": {
"name": "Any",
"kind": "alias",
"path": "mail_intake.credentials.redis.Any",
"signature": "<bound method Alias.signature of Alias('Any', 'typing.Any')>",
"docstring": null
}
}
},

View File

@@ -11,6 +11,13 @@
"signature": "<bound method Alias.signature of Alias('Callable', 'collections.abc.Callable')>",
"docstring": null
},
"Any": {
"name": "Any",
"kind": "alias",
"path": "mail_intake.credentials.redis.Any",
"signature": "<bound method Alias.signature of Alias('Any', 'typing.Any')>",
"docstring": null
},
"TypeVar": {
"name": "TypeVar",
"kind": "alias",
@@ -59,7 +66,7 @@
"name": "RedisCredentialStore",
"kind": "class",
"path": "mail_intake.credentials.redis.RedisCredentialStore",
"signature": "<bound method Class.signature of Class('RedisCredentialStore', 35, 137)>",
"signature": "<bound method Class.signature of Class('RedisCredentialStore', 35, 145)>",
"docstring": "Redis-backed implementation of `CredentialStore`.\n\nThis store persists credentials in Redis and is suitable for\ndistributed and horizontally scaled deployments where credentials\nmust be shared across multiple processes or nodes.\n\nNotes:\n **Responsibilities:**\n\n - This class is responsible only for persistence and retrieval.\n - It does not interpret, validate, refresh, or otherwise manage the\n lifecycle of the credentials being stored.\n\n **Guarantees:**\n\n - The store is intentionally generic and delegates all serialization\n concerns to caller-provided functions.\n - This avoids unsafe mechanisms such as `pickle` and allows\n credential formats to be explicitly controlled and audited.",
"members": {
"redis": {
@@ -101,31 +108,24 @@
"name": "load",
"kind": "function",
"path": "mail_intake.credentials.redis.RedisCredentialStore.load",
"signature": "<bound method Function.signature of Function('load', 80, 105)>",
"signature": "<bound method Function.signature of Function('load', 88, 113)>",
"docstring": "Load credentials from Redis.\n\nReturns:\n T | None:\n An instance of type `T` if credentials are present and\n successfully deserialized; otherwise `None`.\n\nNotes:\n **Guarantees:**\n\n - If no value exists for the configured key, or if the stored\n payload cannot be successfully deserialized, this method\n returns `None`.\n - The store does not attempt to validate the returned\n credentials or determine whether they are expired or\n otherwise usable."
},
"save": {
"name": "save",
"kind": "function",
"path": "mail_intake.credentials.redis.RedisCredentialStore.save",
"signature": "<bound method Function.signature of Function('save', 107, 125)>",
"signature": "<bound method Function.signature of Function('save', 115, 133)>",
"docstring": "Persist credentials to Redis.\n\nArgs:\n credentials (T):\n The credential object to persist.\n\nNotes:\n **Responsibilities:**\n\n - Any previously stored credentials under the same key are overwritten\n - If a TTL is configured, the credentials will expire automatically after the specified duration"
},
"clear": {
"name": "clear",
"kind": "function",
"path": "mail_intake.credentials.redis.RedisCredentialStore.clear",
"signature": "<bound method Function.signature of Function('clear', 127, 137)>",
"signature": "<bound method Function.signature of Function('clear', 135, 145)>",
"docstring": "Remove stored credentials from Redis.\n\nNotes:\n **Lifecycle:**\n\n - This operation deletes the configured Redis key if it exists\n - Implementations should treat this method as idempotent"
}
}
},
"Any": {
"name": "Any",
"kind": "alias",
"path": "mail_intake.credentials.redis.Any",
"signature": "<bound method Alias.signature of Alias('Any', 'typing.Any')>",
"docstring": null
}
}
}

View File

@@ -891,6 +891,13 @@
"signature": "<bound method Alias.signature of Alias('Callable', 'collections.abc.Callable')>",
"docstring": null
},
"Any": {
"name": "Any",
"kind": "alias",
"path": "mail_intake.credentials.redis.Any",
"signature": "<bound method Alias.signature of Alias('Any', 'typing.Any')>",
"docstring": null
},
"TypeVar": {
"name": "TypeVar",
"kind": "alias",
@@ -939,7 +946,7 @@
"name": "RedisCredentialStore",
"kind": "class",
"path": "mail_intake.credentials.redis.RedisCredentialStore",
"signature": "<bound method Class.signature of Class('RedisCredentialStore', 35, 137)>",
"signature": "<bound method Class.signature of Class('RedisCredentialStore', 35, 145)>",
"docstring": "Redis-backed implementation of `CredentialStore`.\n\nThis store persists credentials in Redis and is suitable for\ndistributed and horizontally scaled deployments where credentials\nmust be shared across multiple processes or nodes.\n\nNotes:\n **Responsibilities:**\n\n - This class is responsible only for persistence and retrieval.\n - It does not interpret, validate, refresh, or otherwise manage the\n lifecycle of the credentials being stored.\n\n **Guarantees:**\n\n - The store is intentionally generic and delegates all serialization\n concerns to caller-provided functions.\n - This avoids unsafe mechanisms such as `pickle` and allows\n credential formats to be explicitly controlled and audited.",
"members": {
"redis": {
@@ -981,31 +988,24 @@
"name": "load",
"kind": "function",
"path": "mail_intake.credentials.redis.RedisCredentialStore.load",
"signature": "<bound method Function.signature of Function('load', 80, 105)>",
"signature": "<bound method Function.signature of Function('load', 88, 113)>",
"docstring": "Load credentials from Redis.\n\nReturns:\n T | None:\n An instance of type `T` if credentials are present and\n successfully deserialized; otherwise `None`.\n\nNotes:\n **Guarantees:**\n\n - If no value exists for the configured key, or if the stored\n payload cannot be successfully deserialized, this method\n returns `None`.\n - The store does not attempt to validate the returned\n credentials or determine whether they are expired or\n otherwise usable."
},
"save": {
"name": "save",
"kind": "function",
"path": "mail_intake.credentials.redis.RedisCredentialStore.save",
"signature": "<bound method Function.signature of Function('save', 107, 125)>",
"signature": "<bound method Function.signature of Function('save', 115, 133)>",
"docstring": "Persist credentials to Redis.\n\nArgs:\n credentials (T):\n The credential object to persist.\n\nNotes:\n **Responsibilities:**\n\n - Any previously stored credentials under the same key are overwritten\n - If a TTL is configured, the credentials will expire automatically after the specified duration"
},
"clear": {
"name": "clear",
"kind": "function",
"path": "mail_intake.credentials.redis.RedisCredentialStore.clear",
"signature": "<bound method Function.signature of Function('clear', 127, 137)>",
"signature": "<bound method Function.signature of Function('clear', 135, 145)>",
"docstring": "Remove stored credentials from Redis.\n\nNotes:\n **Lifecycle:**\n\n - This operation deletes the configured Redis key if it exists\n - Implementations should treat this method as idempotent"
}
}
},
"Any": {
"name": "Any",
"kind": "alias",
"path": "mail_intake.credentials.redis.Any",
"signature": "<bound method Alias.signature of Alias('Any', 'typing.Any')>",
"docstring": null
}
}
},

View File

@@ -25,7 +25,7 @@ responsibility of authentication provider implementations.
"""
from collections.abc import Callable
from typing import TypeVar
from typing import Any, TypeVar
from mail_intake.credentials.store import CredentialStore
@@ -57,7 +57,7 @@ class RedisCredentialStore(CredentialStore[T]):
def __init__(
self,
redis_client,
redis_client: Any,
key: str,
serialize: Callable[[T], bytes],
deserialize: Callable[[bytes], T],
@@ -66,10 +66,18 @@ class RedisCredentialStore(CredentialStore[T]):
"""
Initialize a Redis-backed credential store.
Callers supply all runtime dependencies: ``redis_client`` is an
initialized Redis client instance, ``key`` names the storage key,
``serialize``/``deserialize`` are the encoding and decoding callables,
and ``ttl_seconds`` optionally limits credential lifetime.
Args:
redis_client (Any):
Initialized Redis client instance used for persistence.
key (str):
Storage key under which credentials are persisted.
serialize (Callable[[T], bytes]):
Callable that encodes credentials to bytes for storage.
deserialize (Callable[[bytes], T]):
Callable that decodes stored bytes back into credentials.
ttl_seconds (int | None):
Optional time-to-live in seconds after which stored
credentials expire automatically. ``None`` disables expiry.
"""
self.redis = redis_client
self.key = key