Skip to content

Instantly share code, notes, and snippets.

@simonw
Created July 10, 2023 18:25
Show Gist options
  • Save simonw/d3d4773666b863e628b1a60d5a20294d to your computer and use it in GitHub Desktop.
Save simonw/d3d4773666b863e628b1a60d5a20294d to your computer and use it in GitHub Desktop.
Tiny ASGI app demonstrating server-sent events
import asyncio
from pprint import pprint
async def app(scope, receive, send):
if scope["type"] == "http":
if scope["path"] == "/":
await homepage(send)
elif scope["path"] == "/subscribe":
await subscribe(scope, send)
async def homepage(send):
await send(
{
"type": "http.response.start",
"status": 200,
"headers": [
[b"content-type", b"text/html"],
],
}
)
await send(
{
"type": "http.response.body",
"body": b"""
<html>
<head>
<title>Subscribe Endpoint Demonstration</title>
<script>
let eventSource;
function start() {
const id = 1234;
eventSource = new EventSource(`/subscribe?id=${id}`);
eventSource.onmessage = function (event) {
const para = document.createElement("p");
para.innerText = event.data;
document.body.appendChild(para);
};
}
function stop() {
eventSource.close();
}
</script>
</head>
<body>
<button onclick="start()">Start</button>
<button onclick="stop()">Stop</button>
</body>
</html>
""",
}
)
async def subscribe(scope, send):
pprint(scope)
last_event_id = next(
(value for key, value in scope["headers"] if key == b"last-event-id"), b"0"
).decode()
id = int(scope["query_string"].decode().split("=")[1])
start = id if last_event_id == "0" else int(last_event_id)
await send(
{
"type": "http.response.start",
"status": 200,
"headers": [
[b"content-type", b"text/event-stream"],
],
}
)
for i in range(start, start + 10):
await send(
{
"type": "http.response.body",
"body": f"id: {i}\ndata: {i}\n\n".encode(),
"more_body": True,
}
)
await asyncio.sleep(1)
await send(
{
"type": "http.response.body",
"body": b"",
}
)
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="0.0.0.0", port=8000)
@simonw
Copy link
Author

simonw commented Jul 10, 2023

Run it like this:

python -m pip install uvicorn
python server_sent_events.py

I wrote this with GPT-4: https://chat.openai.com/share/edb7149f-0ec6-457e-9bf6-f554e72b0621

I added the pprint(scope) bit.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment