ForkAnthropicAnthropicpublished Dec 28, 2022seen 6d

anthropics/sse-starlette

forked from sysid/sse-starlette

Open original ↗

Captured source

source ↗
published Dec 28, 2022seen 6dcaptured 9hhttp 200method plain

anthropics/sse-starlette

License: BSD-3-Clause

Stars: 9

Forks: 6

Open issues: 0

Created: 2022-12-28T07:32:54Z

Pushed: 2022-12-27T16:06:16Z

Default branch: master

Fork: yes

Parent repository: sysid/sse-starlette

Archived: no

README:

Server Sent Events for Starlette and FastAPI

[![PyPI Version][pypi-image]][pypi-url] [![Build Status][build-image]][build-url] [![Code Coverage][coverage-image]][coverage-url]

Background: https://sysid.github.io/server-sent-events/

Installation:

pip install sse-starlette

Usage:

import asyncio
import uvicorn
from starlette.applications import Starlette
from starlette.routing import Route
from sse_starlette.sse import EventSourceResponse

async def numbers(minimum, maximum):
for i in range(minimum, maximum + 1):
await asyncio.sleep(0.9)
yield dict(data=i)

async def sse(request):
generator = numbers(1, 5)
return EventSourceResponse(generator)

routes = [
Route("/", endpoint=sse)
]

app = Starlette(debug=True, routes=routes)

if __name__ == "__main__":
uvicorn.run(app, host="0.0.0.0", port=8000, log_level='info')

Output: ![output](output.png)

Caveat: SSE streaming does not work in combination with GZipMiddleware.

Be aware that for proper server shutdown your application must stop all running tasks (generators). Otherwise you might experience the following warnings at shutdown: Waiting for background tasks to complete. (CTRL+C to force quit).

Client disconnects need to be handled in your Request handler (see example.py):

async def endless(req: Request):
async def event_publisher():
i = 0
try:
while True:
i += 1
yield dict(data=i)
await asyncio.sleep(0.2)
except asyncio.CancelledError as e:
_log.info(f"Disconnected from client (via refresh/close) {req.client}")
# Do any other cleanup, if any
raise e
return EventSourceResponse(event_publisher())

Run the tests:

make test

Special use cases

Fan out Proxies

Fan out proxies usually rely on response being cacheable. To support that, you can set the value of Cache-Control. For example:

return EventSourceResponse(
generator(), headers={"Cache-Control": "public, max-age=29"}
)

Changelog

CHANGELOG.md

[pypi-image]: https://badge.fury.io/py/sse-starlette.svg [pypi-url]: https://pypi.org/project/sse-starlette/ [build-image]: https://github.com/sysid/sse-starlette/actions/workflows/build.yml/badge.svg [build-url]: https://github.com/sysid/sse-starlette/actions/workflows/build.yml [coverage-image]: https://codecov.io/gh/sysid/sse-starlette/branch/master/graph/badge.svg [coverage-url]: https://codecov.io/gh/sysid/sse-starlette