Buckets:
MisterAI/LocalAI_Demo_backends / cpu-pocket-tts.upgrade-tmp /venv /lib /python3.10 /site-packages /fastapi /sse.py
| from typing import Annotated, Any | |
| from annotated_doc import Doc | |
| from pydantic import AfterValidator, BaseModel, Field, model_validator | |
| from starlette.responses import StreamingResponse | |
| # Canonical SSE event schema matching the OpenAPI 3.2 spec | |
| # (Section 4.14.4 "Special Considerations for Server-Sent Events") | |
| _SSE_EVENT_SCHEMA: dict[str, Any] = { | |
| "type": "object", | |
| "properties": { | |
| "data": {"type": "string"}, | |
| "event": {"type": "string"}, | |
| "id": {"type": "string"}, | |
| "retry": {"type": "integer", "minimum": 0}, | |
| }, | |
| } | |
| class EventSourceResponse(StreamingResponse): | |
| """Streaming response with `text/event-stream` media type. | |
| Use as `response_class=EventSourceResponse` on a *path operation* that uses `yield` | |
| to enable Server Sent Events (SSE) responses. | |
| Works with **any HTTP method** (`GET`, `POST`, etc.), which makes it compatible | |
| with protocols like MCP that stream SSE over `POST`. | |
| The actual encoding logic lives in the FastAPI routing layer. This class | |
| serves mainly as a marker and sets the correct `Content-Type`. | |
| """ | |
| media_type = "text/event-stream" | |
| def _check_single_line(v: str | None, field_name: str) -> str | None: | |
| if v is not None and ("\r" in v or "\n" in v): | |
| raise ValueError(f"SSE '{field_name}' must be a single line") | |
| return v | |
| def _check_event_single_line(v: str | None) -> str | None: | |
| return _check_single_line(v, "event") | |
| def _check_id_valid(v: str | None) -> str | None: | |
| if v is not None and "\0" in v: | |
| raise ValueError("SSE 'id' must not contain null characters") | |
| return _check_single_line(v, "id") | |
| class ServerSentEvent(BaseModel): | |
| """Represents a single Server-Sent Event. | |
| When `yield`ed from a *path operation function* that uses | |
| `response_class=EventSourceResponse`, each `ServerSentEvent` is encoded | |
| into the [SSE wire format](https://html.spec.whatwg.org/multipage/server-sent-events.html#parsing-an-event-stream) | |
| (`text/event-stream`). | |
| If you yield a plain object (dict, Pydantic model, etc.) instead, it is | |
| automatically JSON-encoded and sent as the `data:` field. | |
| All `data` values **including plain strings** are JSON-serialized. | |
| For example, `data="hello"` produces `data: "hello"` on the wire (with | |
| quotes). | |
| """ | |
| data: Annotated[ | |
| Any, | |
| Doc( | |
| """ | |
| The event payload. | |
| Can be any JSON-serializable value: a Pydantic model, dict, list, | |
| string, number, etc. It is **always** serialized to JSON: strings | |
| are quoted (`"hello"` becomes `data: "hello"` on the wire). | |
| Mutually exclusive with `raw_data`. | |
| """ | |
| ), | |
| ] = None | |
| raw_data: Annotated[ | |
| str | None, | |
| Doc( | |
| """ | |
| Raw string to send as the `data:` field **without** JSON encoding. | |
| Use this when you need to send pre-formatted text, HTML fragments, | |
| CSV lines, or any non-JSON payload. The string is placed directly | |
| into the `data:` field as-is. | |
| Mutually exclusive with `data`. | |
| """ | |
| ), | |
| ] = None | |
| event: Annotated[ | |
| str | None, | |
| AfterValidator(_check_event_single_line), | |
| Doc( | |
| """ | |
| Optional event type name. | |
| Maps to `addEventListener(event, ...)` on the browser. When omitted, | |
| the browser dispatches on the generic `message` event. Must be a | |
| single line. | |
| """ | |
| ), | |
| ] = None | |
| id: Annotated[ | |
| str | None, | |
| AfterValidator(_check_id_valid), | |
| Doc( | |
| """ | |
| Optional event ID. | |
| The browser sends this value back as the `Last-Event-ID` header on | |
| automatic reconnection. **Must be a single line** and must not contain | |
| null (`\\0`) characters. | |
| """ | |
| ), | |
| ] = None | |
| retry: Annotated[ | |
| int | None, | |
| Field(ge=0), | |
| Doc( | |
| """ | |
| Optional reconnection time in **milliseconds**. | |
| Tells the browser how long to wait before reconnecting after the | |
| connection is lost. Must be a non-negative integer. | |
| """ | |
| ), | |
| ] = None | |
| comment: Annotated[ | |
| str | None, | |
| Doc( | |
| """ | |
| Optional comment line(s). | |
| Comment lines start with `:` in the SSE wire format and are ignored by | |
| `EventSource` clients. Useful for keep-alive pings to prevent | |
| proxy/load-balancer timeouts. | |
| """ | |
| ), | |
| ] = None | |
| def _check_data_exclusive(self) -> "ServerSentEvent": | |
| if self.data is not None and self.raw_data is not None: | |
| raise ValueError( | |
| "Cannot set both 'data' and 'raw_data' on the same " | |
| "ServerSentEvent. Use 'data' for JSON-serialized payloads " | |
| "or 'raw_data' for pre-formatted strings." | |
| ) | |
| return self | |
| def format_sse_event( | |
| *, | |
| data_str: Annotated[ | |
| str | None, | |
| Doc( | |
| """ | |
| Pre-serialized data string to use as the `data:` field. | |
| """ | |
| ), | |
| ] = None, | |
| event: Annotated[ | |
| str | None, | |
| Doc( | |
| """ | |
| Optional event type name (`event:` field). | |
| """ | |
| ), | |
| ] = None, | |
| id: Annotated[ | |
| str | None, | |
| Doc( | |
| """ | |
| Optional event ID (`id:` field). | |
| """ | |
| ), | |
| ] = None, | |
| retry: Annotated[ | |
| int | None, | |
| Doc( | |
| """ | |
| Optional reconnection time in milliseconds (`retry:` field). | |
| """ | |
| ), | |
| ] = None, | |
| comment: Annotated[ | |
| str | None, | |
| Doc( | |
| """ | |
| Optional comment line(s) (`:` prefix). | |
| """ | |
| ), | |
| ] = None, | |
| ) -> bytes: | |
| """Build SSE wire-format bytes from **pre-serialized** data. | |
| The result always ends with `\n\n` (the event terminator). | |
| """ | |
| lines: list[str] = [] | |
| if comment is not None: | |
| for line in comment.splitlines(): | |
| lines.append(f": {line}") | |
| if event is not None: | |
| lines.append(f"event: {event}") | |
| if data_str is not None: | |
| for line in data_str.splitlines(): | |
| lines.append(f"data: {line}") | |
| if id is not None: | |
| lines.append(f"id: {id}") | |
| if retry is not None: | |
| lines.append(f"retry: {retry}") | |
| lines.append("") | |
| lines.append("") | |
| return "\n".join(lines).encode("utf-8") | |
| # Keep-alive comment, per the SSE spec recommendation | |
| KEEPALIVE_COMMENT = b": ping\n\n" | |
| # Seconds between keep-alive pings when a generator is idle. | |
| # Private but importable so tests can monkeypatch it. | |
| _PING_INTERVAL: float = 15.0 | |
Xet Storage Details
- Size:
- 6.85 kB
- Xet hash:
- a30cd153e81679cca5ec0b47e560aa0cbed1c869dcf9c5fbacd8d56fabedded0
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.