ASGI request scope¶
The framework-free middleware the Starlette and Litestar integrations specialise. See the request and response integrations for which module to install.
RequestScope ¶
ASGI middleware that opens one depin async scope around every request.
Implemented directly against the ASGI protocol rather than a framework's
HTTP-middleware base class, so streaming responses, server-sent events and
WebSockets pass through without buffering. Every ASGI integration depin
ships specialises this class, supplying only the seed that places its
own framework's request object into the frame.
Connection scopes other than http and websocket are forwarded
untouched, with no depin scope opened. The lifespan scope in particular is
opened once at startup and lives for the whole process: wrapping it would
leak a frame for the application's lifetime and put startup and shutdown
inside a scope that never drains.
For the scopes it does wrap, the container is published to the request's
context for the duration of the scope, so depin.hosted_container()
reaches it from anywhere inside the request. The scope's teardowns run when
the request ends — including when it ends by raising — and the publication
is undone after them.
seed is applied to http connections only. A websocket connection
has no request-body semantics, and the framework request classes the seeds
construct are HTTP-shaped; a websocket therefore gets the scope and the
published container, but no seeded request.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
app
|
ASGIApp[ScopeT, ReceiveT, SendT]
|
The downstream ASGI application this middleware wraps. |
required |
container
|
FrozenContainer
|
The frozen container to host for the duration of each
request. Keyword-or-positional because the framework helpers that
install middleware pass |
required |
seed
|
ScopeSeeder[ScopeT] | None
|
Called once per |
None
|
Raises:
| Type | Description |
|---|---|
ExceptionGroup
|
One or more teardowns failed when the request's scope closed. Every failure is included; one does not hide another. |
Example
Install the middleware once, per the wrapping framework's own idiom::
from depin import ScopeSeed
middleware = RequestScope(app, di, seed=lambda scope: ScopeSeed(Request, Request(scope)))
ASGIApp ¶
Bases: Protocol
Any ASGI application or middleware: the downstream peer RequestScope wraps.
ASGIScope ¶
ASGIScope = Mapping[str, object]
The connection scope: scope['type'] is 'http', 'websocket' or 'lifespan'.
Read-only, because that is the widest shape every framework's own scope type
satisfies: a TypedDict is a collections.abc.Mapping but not a
collections.abc.MutableMapping.
Receive ¶
Bases: Protocol
The channel an ASGI application awaits to read the next inbound event.
Send ¶
Bases: Protocol
The channel an ASGI application awaits to write one outbound event.