Middleware for Starlette that allows you to store and access the context data of a request.
npx @tessl/cli install tessl/pypi-starlette-context@0.4.00
# Starlette Context
1
2
A middleware library for Starlette and FastAPI applications that provides request-scoped context storage and access. Enables automatic inclusion of request headers like x-request-id or x-correlation-id in logs and throughout the request lifecycle with plugin-based architecture.
3
4
## Package Information
5
6
- **Package Name**: starlette-context
7
- **Language**: Python
8
- **Installation**: `pip install starlette-context`
9
- **Requires**: Python 3.9+, starlette >= 0.27.0
10
11
## Core Imports
12
13
```python
14
from starlette_context import context, request_cycle_context
15
```
16
17
For middleware:
18
19
```python
20
from starlette_context.middleware import ContextMiddleware, RawContextMiddleware
21
```
22
23
For plugins:
24
25
```python
26
from starlette_context.plugins import (
27
Plugin,
28
RequestIdPlugin, CorrelationIdPlugin, ApiKeyPlugin,
29
UserAgentPlugin, ForwardedForPlugin, DateHeaderPlugin
30
)
31
```
32
33
For plugin base classes (not directly exported):
34
35
```python
36
from starlette_context.plugins.base import PluginUUIDBase
37
```
38
39
For header constants:
40
41
```python
42
from starlette_context.header_keys import HeaderKeys
43
```
44
45
## Basic Usage
46
47
```python
48
from starlette.applications import Starlette
49
from starlette.responses import JSONResponse
50
from starlette.routing import Route
51
from starlette_context import context
52
from starlette_context.middleware import ContextMiddleware
53
from starlette_context.plugins import RequestIdPlugin, CorrelationIdPlugin
54
55
async def homepage(request):
56
# Access context data like a dictionary
57
request_id = context.get("X-Request-ID")
58
correlation_id = context["X-Correlation-ID"]
59
60
# Store additional data
61
context["custom_data"] = "some value"
62
63
return JSONResponse({
64
"request_id": request_id,
65
"correlation_id": correlation_id,
66
"context_data": context.data
67
})
68
69
app = Starlette(routes=[Route("/", homepage)])
70
71
# Add middleware with plugins
72
app.add_middleware(
73
ContextMiddleware,
74
plugins=(
75
RequestIdPlugin(),
76
CorrelationIdPlugin(force_new_uuid=True)
77
)
78
)
79
```
80
81
## Architecture
82
83
The starlette-context library provides a plugin-based middleware system for request-scoped data management:
84
85
- **Context**: Global dict-like object accessible throughout request lifecycle
86
- **Middleware**: Two implementations (ContextMiddleware, RawContextMiddleware) that manage context lifecycle
87
- **Plugins**: Extensible components that extract/process headers and enrich responses
88
- **Request Cycle**: Context storage using Python's contextvars for async-safe isolation
89
90
The design enables automatic header extraction, context enrichment, response modification, and logging integration while maintaining clean separation between data extraction (plugins) and access (context object).
91
92
## Capabilities
93
94
### Context Management
95
96
Core functionality for accessing and managing request-scoped context data through a global dictionary-like interface.
97
98
```python { .api }
99
context: _Context # Global context instance
100
101
class _Context(UserDict):
102
"""A mapping with dict-like interface using request context as data store."""
103
@property
104
def data(self) -> dict:
105
"""Get context data as dict. Object itself is not serializable."""
106
def exists(self) -> bool:
107
"""Check if context exists in current request cycle."""
108
def copy(self) -> dict:
109
"""Read-only copy of context data."""
110
111
@contextmanager
112
def request_cycle_context(initial_data: Optional[dict] = None) -> Iterator[None]:
113
"""Context manager for creating request-scoped context."""
114
```
115
116
[Context Management](./context-management.md)
117
118
### Middleware Integration
119
120
Two middleware implementations for integrating context management into Starlette/FastAPI applications with different performance characteristics.
121
122
```python { .api }
123
class ContextMiddleware(BaseHTTPMiddleware):
124
def __init__(
125
self,
126
app: ASGIApp,
127
plugins: Optional[Sequence[Plugin]] = None,
128
default_error_response: Response = Response(status_code=400)
129
): ...
130
131
class RawContextMiddleware:
132
def __init__(
133
self,
134
app: ASGIApp,
135
plugins: Optional[Sequence[Plugin]] = None,
136
default_error_response: Response = Response(status_code=400)
137
): ...
138
async def set_context(self, request: Union[Request, HTTPConnection]) -> dict: ...
139
@staticmethod
140
def get_request_object(scope: Scope, receive: Receive, send: Send) -> Union[Request, HTTPConnection]: ...
141
async def send_response(self, error_response: Response, send: Send) -> None: ...
142
async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None: ...
143
```
144
145
[Middleware Integration](./middleware.md)
146
147
### Plugin System
148
149
Extensible plugin architecture for extracting data from requests and enriching responses, with built-in plugins for common use cases.
150
151
```python { .api }
152
class Plugin(metaclass=abc.ABCMeta):
153
key: str
154
async def process_request(self, request: Union[Request, HTTPConnection]) -> Optional[Any]: ...
155
async def enrich_response(self, arg: Union[Response, Message]) -> None: ...
156
157
class PluginUUIDBase(Plugin):
158
def __init__(
159
self,
160
force_new_uuid: bool = False,
161
version: int = 4,
162
validate: bool = True,
163
error_response: Optional[Response] = None
164
): ...
165
```
166
167
[Plugin System](./plugins.md)
168
169
### Error Handling
170
171
Comprehensive error handling for context lifecycle, configuration, and plugin validation with custom response support.
172
173
```python { .api }
174
class ContextDoesNotExistError(RuntimeError, StarletteContextError): ...
175
class ConfigurationError(StarletteContextError): ...
176
class MiddleWareValidationError(StarletteContextError):
177
def __init__(self, *args: Any, error_response: Optional[Response] = None): ...
178
class WrongUUIDError(MiddleWareValidationError): ...
179
class DateFormatError(MiddleWareValidationError): ...
180
```
181
182
[Error Handling](./error-handling.md)
183
184
## Types
185
186
```python { .api }
187
from typing import Any, Optional, Union, Sequence, Iterator
188
from collections.abc import Iterator
189
from contextlib import contextmanager
190
from contextvars import ContextVar, Token
191
from enum import Enum
192
import abc
193
import datetime
194
from starlette.requests import Request, HTTPConnection
195
from starlette.responses import Response
196
from starlette.types import ASGIApp, Message, Receive, Scope, Send
197
from starlette.middleware.base import BaseHTTPMiddleware
198
199
class HeaderKeys(str, Enum):
200
api_key = "X-API-Key"
201
correlation_id = "X-Correlation-ID"
202
request_id = "X-Request-ID"
203
date = "Date"
204
forwarded_for = "X-Forwarded-For"
205
user_agent = "User-Agent"
206
```