Server-Sent Events
Server-sent events (SSE) let a server push a stream of events to the client over a single long-lived HTTP response with the text/event-stream content type. HTTPX has native support for consuming them through client.sse().
Consuming events
client.sse() is a context manager that yields an EventSource. Iterating the EventSource decodes the stream and yields a ServerSentEvent for each event:
>>> with httpx2.Client() as client:
... with client.sse("https://example.com/sse") as source:
... for event in source:
... print(event.event, event.data)
It works the same way with the async client, using async with and async for:
>>> async with httpx2.AsyncClient() as client:
... async with client.sse("https://example.com/sse") as source:
... async for event in source:
... print(event.event, event.data)
sse() issues a GET request by default. Some APIs stream events in response to a POST - pass method="POST" along with the usual request arguments:
>>> with client.sse("https://example.com/sse", method="POST", json={"query": "..."}) as source:
... for event in source:
... print(event.data)
The Accept: text/event-stream and Cache-Control: no-store headers are set for you; any headers you pass take precedence.
The ServerSentEvent
Each event exposes the fields defined by the SSE specification:
| Attribute | Description |
|---|---|
event |
The event type. Defaults to "message". |
data |
The event payload. Multiple data: lines are joined with \n. |
id |
The last event ID, which persists across events until changed. |
retry |
The reconnection time in milliseconds, or None. |
When the payload is JSON, event.json() decodes event.data for you:
>>> with client.sse("https://example.com/sse") as source:
... for event in source:
... print(event.json())
Accessing the response
The underlying Response is available as source.response, which is useful for inspecting the status code or headers before iterating:
>>> with client.sse("https://example.com/sse") as source:
... source.response.raise_for_status()
... for event in source:
... print(event.data)
Error handling
If the response does not have a text/event-stream content type, iterating the EventSource raises SSEError:
>>> with client.sse("https://example.com/not-an-event-stream") as source:
... for event in source: # raises httpx2.SSEError
... ...
SSEError is a subclass of TransportError, so it is also caught by except httpx2.TransportError.