refactor: centralize ndjson streaming transport
This commit is contained in:
@@ -3,6 +3,7 @@ from __future__ import annotations
|
||||
import json
|
||||
import mimetypes
|
||||
import secrets
|
||||
from collections.abc import Iterable
|
||||
from http import HTTPStatus
|
||||
from http.cookies import SimpleCookie
|
||||
from typing import Any
|
||||
@@ -142,5 +143,33 @@ class HttpTransportMixin:
|
||||
self.end_headers()
|
||||
self.wfile.write(content)
|
||||
|
||||
def _write_stream_event(self, payload: dict[str, Any]) -> None:
|
||||
self.wfile.write(
|
||||
(json.dumps(payload, ensure_ascii=False, separators=(",", ":")) + "\n").encode("utf-8")
|
||||
)
|
||||
self.wfile.flush()
|
||||
|
||||
def send_ndjson_stream(
|
||||
self,
|
||||
events: Iterable[dict[str, Any]],
|
||||
error_types: tuple[type[Exception], ...],
|
||||
) -> None:
|
||||
self.send_response(HTTPStatus.OK)
|
||||
self.send_header("Content-Type", "application/x-ndjson; charset=utf-8")
|
||||
self.send_header("Cache-Control", "no-cache, no-transform")
|
||||
self.send_header("X-Accel-Buffering", "no")
|
||||
self.send_header("Connection", "close")
|
||||
self.end_headers()
|
||||
try:
|
||||
for event in events:
|
||||
self._write_stream_event(event)
|
||||
self._write_stream_event({"type": "done"})
|
||||
except error_types as exc:
|
||||
self._write_stream_event({"type": "error", "error": str(exc)})
|
||||
except (BrokenPipeError, ConnectionResetError):
|
||||
pass
|
||||
finally:
|
||||
self.close_connection = True
|
||||
|
||||
def log_message(self, format_string: str, *args: Any) -> None:
|
||||
print(f"[{self.log_date_time_string()}] {format_string % args}")
|
||||
|
||||
Reference in New Issue
Block a user