Module

asgi.sync_bridge

Sync ASGI bridge — run ASGI apps from a synchronous context.

For simple request-response (no streaming receive, no streaming send), collects the response in memory and returns it as a SyncResponse.

If the app sends more_body=True (streaming) or the scope type is websocket, raises NeedsAsyncError so the caller can hand off to the async pool.

Classes

NeedsAsyncError 0
Raised when the ASGI app requires async (streaming, WebSocket). The SyncWorker catches this and ha…
Bases: Exception

Raised when the ASGI app requires async (streaming, WebSocket).

The SyncWorker catches this and hands off the connection to the AsyncPool for multiplexed I/O handling.

SyncResponse 4
Complete HTTP response from a sync ASGI invocation.

Complete HTTP response from a sync ASGI invocation.

Attributes

Name Type Description
status int

HTTP status code.

headers list[tuple[bytes, bytes]]

Response headers as list of (name, value) byte pairs.

body bytes

Full response body bytes.

needs_async bool

True if the app indicated streaming (more_body=True).

Functions

call_asgi_sync 4 SyncResponse
Run an ASGI app from a sync context. For simple request-response (no streaming…
def call_asgi_sync(app: ASGIApp, scope: dict[str, Any], body: bytes, *, runner: asyncio.Runner | None = None) -> SyncResponse

Run an ASGI app from a sync context.

For simple request-response (no streaming receive, no streaming send), this collects the response in memory and returns it as a SyncResponse.

If the app sends more_body=True (streaming), sets needs_async=True on the response so the caller can hand off. The response may be partial (headers + first body chunk).

Raises NeedsAsyncError immediately for WebSocket scopes (caller must hand off before invoking the app).

Parameters
Name Type Description
app ASGIApp

The ASGI application.

scope dict[str, Any]

ASGI scope dict.

body bytes

Full request body (for non-streaming requests).

runner asyncio.Runner | None

Reusable asyncio.Runner owned by the calling worker thread. Avoids creating/destroying an event loop per request. When None, a temporary Runner is created (slow fallback).

Default:None
Returns
SyncResponse