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
delete_context(ctx_type, context_id)
abstractmethod
async
¶
Delete a context.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ctx_type
|
type[ContextTypeT]
|
The type of context to delete |
required |
context_id
|
UUID
|
The UUID identifying the context |
required |
Raises:
| Type | Description |
|---|---|
KeyError
|
If the context does not exist |
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
92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 | |
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
delete_context(ctx_type, context_id)
async
¶
Delete a context and its lock.
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.