mirror of
https://github.com/jxxghp/MoviePilot.git
synced 2026-08-29 20:17:13 +08:00
45 lines
1.3 KiB
Python
45 lines
1.3 KiB
Python
"""SSE wire mapping and response lifecycle helpers."""
|
|
|
|
import json
|
|
from collections.abc import AsyncIterable, Iterable
|
|
from typing import Any
|
|
|
|
from fastapi.responses import StreamingResponse
|
|
|
|
SSE_HEADERS = {
|
|
"Cache-Control": "no-cache, no-transform",
|
|
"Connection": "keep-alive",
|
|
"X-Accel-Buffering": "no",
|
|
}
|
|
|
|
|
|
def encode_data_event(payload: dict[str, Any]) -> str:
|
|
"""Encode an OpenAI-style unnamed SSE data event."""
|
|
return f"data: {json.dumps(payload, ensure_ascii=False)}\n\n"
|
|
|
|
|
|
def encode_named_event(event: str, payload: dict[str, Any]) -> str:
|
|
"""Encode a named SSE event without applying a response envelope."""
|
|
return (
|
|
f"event: {event}\n"
|
|
f"data: {json.dumps(payload, ensure_ascii=False)}\n\n"
|
|
)
|
|
|
|
|
|
def build_sse_response(
|
|
content: AsyncIterable[str] | Iterable[str],
|
|
*,
|
|
headers: dict[str, str] | None = None,
|
|
) -> StreamingResponse:
|
|
"""Build a non-buffered SSE response and merge protocol-specific headers."""
|
|
return StreamingResponse(
|
|
content,
|
|
media_type="text/event-stream",
|
|
headers={**SSE_HEADERS, **(headers or {})},
|
|
)
|
|
|
|
|
|
def build_sse_error_response(payload: str) -> StreamingResponse:
|
|
"""Build a one-event SSE error response using the common transport policy."""
|
|
return build_sse_response(iter([payload]))
|