sse-starlette
Production-ready Server-Sent Events streaming for Starlette and FastAPI, with graceful shutdown and multi-loop support.
Repository Health
Technical Analysis
sse-starlette provides EventSourceResponse, a drop-in Starlette response class that implements the W3C Server-Sent Events specification for streaming real-time updates over plain HTTP. It plugs directly into Starlette routes and FastAPI endpoints, accepting either a sync iterator or an async generator that yields dicts, strings, or ServerSentEvent objects, and handles the wire-format encoding, keep-alive pings, and connection lifecycle automatically.
Beyond basic streaming, the library focuses on production correctness: automatic client-disconnect detection, configurable per-send timeouts, and a cooperative shutdown mechanism that lets a generator emit a farewell event and exit cleanly within a grace period before the server force-cancels it on SIGTERM. It also tracks Starlette’s own StreamingResponse internals closely (task-group cancellation, ExceptionGroup collapsing, WebSocket-denial parity) while deliberately diverging in a few documented spots to preserve disconnect-driven cleanup and multi-threaded/multi-event-loop safety.
What You Get
EventSourceResponse— a StarletteResponsesubclass that streams from any sync iterator or async generator, encoding output to the SSE wire format automaticallyServerSentEventandJSONServerSentEventhelper classes for constructing individual events withdata,event,id,retry, andcommentfields- Automatic keep-alive pings on a configurable interval, plus a
ping_message_factoryhook to customize the ping payload - Client-disconnect detection via
request.is_disconnected()-style monitoring, with an optionalclient_close_handler_callablecallback - Cooperative shutdown support (
shutdown_event+shutdown_grace_period) so generators can send a farewell event and exit gracefully instead of receiving an abruptCancelledErroron server termination - Per-send
send_timeoutto detect and abort hung client connections instead of leaking server-side tasks indefinitely
Common Use Cases
- Streaming LLM token-by-token responses from a FastAPI backend to a web UI, similar to how ChatGPT-style chat interfaces render text incrementally
- Pushing live progress updates (build logs, job status, upload percentage) from a long-running backend task to a browser without polling
- Broadcasting notifications or activity feeds to connected clients using a lightweight, HTTP-native alternative to WebSockets
- Building dashboards that need a continuous feed of metrics or events without the added complexity of a WebSocket server and reconnect logic
Under The Hood
Architecture
EventSourceResponse subclasses Starlette’s Response and, in __call__, spins up an anyio task group running several concurrent coroutines — _stream_response (drains the body iterator and writes ASGI http.response.body messages), _ping (periodic keep-alive), _listen_for_exit_signal_with_grace (shutdown coordination), and _listen_for_disconnect (watches receive() for http.disconnect), plus an optional data_sender_callable — each wrapped in a helper that tears down the whole group once any one of them completes. A module-level AppStatus class monkey-patches uvicorn’s Server.handle_exit to catch SIGTERM, and a thread-local shutdown-state/watcher pair broadcasts that signal to every active response on the same event loop via an anyio.Event, decoupling shutdown from any single response’s lifecycle. Data flows one way: iterator yields (dict/str/event object) get encoded to the SSE wire format and pushed as ASGI body chunks, with a lock guarding concurrent writers (ping vs. stream) from interleaving.
Tech Stack A pure Python 3.10+ package with exactly two runtime dependencies — Starlette for the base response primitives and anyio for the task group, locks, events, and cancel-scope timeouts that give it asyncio/trio parity. The build backend is setuptools via PEP 621 metadata, dependency and dev-tooling management is uv with a committed lockfile, linting/formatting is ruff, and static typing is checked with a modern Rust-based type checker rather than mypy. Optional extras pull in FastAPI, pydantic, SQLAlchemy, and alternative ASGI servers strictly for the bundled examples, never at core runtime. CI runs on GitHub Actions, and pre-commit enforces formatting, linting, and type checks on every commit.
Code Quality The test suite spans multiple dedicated modules covering core streaming behavior, event encoding, parity with Starlette’s own streaming response, multi-loop safety, and targeted regression tests named directly after the GitHub issues that produced them — run under pytest with async test support, integration helpers, and coverage tooling wired in. Error handling is explicit and typed: a custom timeout exception is raised deliberately rather than swallowed, invalid configuration raises specific typed errors, and a small vendored utility exists purely to unwrap anyio’s exception groups back to the underlying exception so callers don’t need special-case handling. Naming is consistent, and the primary module’s docstring explicitly documents several deliberate divergences from Starlette’s own internals with rationale — unusually disciplined inline documentation for a library this size.
What Makes It Unique The main differentiator isn’t the SSE wire-format encoding itself, which is straightforward and spec-driven, but the shutdown and lifecycle handling: monkey-patching uvicorn’s exit handler to detect SIGTERM without requiring the app author to wire anything up, combined with an opt-in cooperative-shutdown grace period so in-flight streams can send a farewell event before being cancelled — a real production pain point during rolling deploys that a plain streaming response doesn’t solve. The move from a context-local to a thread-local shutdown-state implementation, made in direct response to a filed multi-threading bug, shows a library that has iterated through real production issues rather than staying purely theoretical. These are incremental, battle-tested engineering refinements to a narrow, well-defined problem rather than a novel algorithm.
Used by 9 apps in this directory
agenta
Developer Tools · Devops · AI Development
The open-source LLMOps platform unifying prompt engineering, evaluation, and observability for teams building reliable LLM applications.
Agno
Devops · AI Development · Automation
Build, run, and manage agent platforms with a full production stack — SDK, runtime, and control plane included.
Flowsint
Automation · Developer Tools
A privacy-first, graph-based OSINT investigation platform with 30+ automated enrichers for mapping relationships between domains, IPs, people, and organizations.
GPT Researcher
Productivity · AI Assistants
The pioneering open-source autonomous AI agent that conducts deep, multi-source research and produces citation-backed reports exceeding 2,000 words — faster and more reliably than any human researcher.
OpenHands
AI Code Assistants · AI Development
The self-hosted developer control center for running AI coding agents — locally, in Docker, on VMs, or across cloud backends — with automation workflows for GitHub, Slack, and more.
Polar
Ecommerce · Developer Tools · Invoicing Finance
Open source payments infrastructure that turns software into a business — subscriptions, usage-based billing, digital products, and merchant-of-record compliance in one platform.
Skyvern
AI Agents · Automation
Skyvern (YC S2023) automates browser-based workflows by pairing LLMs with computer vision, letting agents click, fill, and extract data on sites they've never seen, without brittle XPath selectors that break on every layout change.
SurfSense
Search · AI Assistants
The open-source, unlimited NotebookLM alternative with real-time collaboration, a desktop app, and no vendor lock-in.
Voicebox
AI Development · Productivity
Clone voices, dictate anywhere, and give AI agents your voice — all locally.