Context Storage API¶
Module: wepositive_di.context
ContextStorage
¶
Bases: ABC
ContextStorage interface.
This interface allows for different storage backends (in-memory, Redis, etc.) to be used for storing context data, keyed by both context type and UUID.
One storage instance can hold multiple context types simultaneously. Implementations must be thread-safe and async-safe.
get_context is an async context manager that yields the context while holding a lock, ensuring safe modifications during the entire usage period.
Source code in src/wepositive_di/context.py
get_context(ctx_type, context_id)
abstractmethod
¶
Get a context for the given type and context_id.
This is an async context manager that yields the context while holding a lock. The lock is held until the context manager exits.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ctx_type
|
type[ContextTypeT]
|
The type of context to retrieve |
required |
context_id
|
UUID
|
The UUID identifying the context |
required |
Yields:
| Type | Description |
|---|---|
AbstractAsyncContextManager[ContextTypeT]
|
The context associated with this type and identifier |
Raises:
| Type | Description |
|---|---|
KeyError
|
If the context does not exist |
Source code in src/wepositive_di/context.py
store_context(ctx_type, context_id, context)
abstractmethod
async
¶
Store a new context.
This creates or replaces a context for the given type and context_id. Thread-safe and async-safe.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ctx_type
|
type[ContextTypeT]
|
The type of context being stored |
required |
context_id
|
UUID
|
The UUID identifying the context |
required |
context
|
ContextTypeT
|
The context to store |
required |
Source code in src/wepositive_di/context.py
get_context_snapshot(ctx_type, context_id)
abstractmethod
async
¶
Get a read-only snapshot source without taking the context lock.
This is intended for event emission paths that must not wait behind a long-running mutable context lock.
Source code in src/wepositive_di/context.py
InMemoryContextStorage
¶
Bases: ContextStorage
Unified in-memory storage for contexts that works in both async and threaded environments.
Uses aiologic.RLock for synchronization, which works seamlessly across: - Pure async servers (FastAPI with single event loop) - Threaded servers with multiple threads - Hybrid environments (multiple threads each with their own event loop)
Contexts are stored in a two-level dict keyed first by context type, then by UUID. Fine-grained per-(type, id) locking allows concurrent access to different contexts.
Note: This implementation is single-process only. For multi-process deployments (e.g., gunicorn with multiple processes), consider using a distributed storage backend like Redis.
Source code in src/wepositive_di/context.py
store_context(ctx_type, context_id, context)
async
¶
Store a new context.
Thread-safe creation/replacement of context. Acquires the fine-grained lock for this (ctx_type, context_id) pair.
Source code in src/wepositive_di/context.py
context_storage_singleton()
¶
Singleton provider for the context storage.
Returns the same InMemoryContextStorage instance for the lifetime of the application. One instance can hold all context types, keyed by (type, UUID).
This implementation uses aiologic.RLock which works seamlessly in: - Async servers (FastAPI): Non-blocking async synchronization - Threaded servers: Thread-safe synchronization - Hybrid environments: Multiple threads with event loops per thread
For multi-process deployments, replace with RedisContextStorage or another distributed storage implementation.