Files
PacketStation/server/packetstation/api/events.py
T

35 lines
1.3 KiB
Python
Raw Normal View History

"""`GET /api/events`: the server-sent event stream (session required; locked sessions allowed)."""
from __future__ import annotations
from fastapi import APIRouter, Query, Request
from fastapi.responses import StreamingResponse
from starlette.concurrency import run_in_threadpool
from ..auth.groups import SCREENS
from ..events import EventHub, stream
from .deps import resolve_standalone, settings_of
router = APIRouter(prefix="/api", tags=["events"])
SSE_HEADERS = {"Cache-Control": "no-cache", "X-Accel-Buffering": "no", "Connection": "keep-alive"}
@router.get("/events")
async def events(request: Request, screen: str | None = Query(None, max_length=32)) -> StreamingResponse:
# The session check runs on its own pooled connection, returned before the stream starts
p = await run_in_threadpool(resolve_standalone, request)
hub: EventHub = request.app.state.events
sub = hub.subscribe(
session_id=p.session_id,
user_id=p.user_id,
display_name=p.user["display_name"],
screen=screen if screen in SCREENS and screen in p.screens else None,
)
hello = {"session_id": str(p.session_id), "build": settings_of(request).ps_build}
return StreamingResponse(
stream(hub, sub, hello=hello, is_disconnected=request.is_disconnected),
media_type="text/event-stream",
headers=SSE_HEADERS,
)