diff --git a/fastapi/sse.py b/fastapi/sse.py index 1e2bd8617..845001dde 100644 --- a/fastapi/sse.py +++ b/fastapi/sse.py @@ -213,7 +213,9 @@ def format_sse_event( lines.append(f"event: {event}") if data_str is not None: - for line in data_str.splitlines(): + # An empty data payload must still emit a single `data:` field; + # `"".splitlines()` returns `[]`, which would drop the field entirely. + for line in data_str.splitlines() or [""]: lines.append(f"data: {line}") if id is not None: diff --git a/tests/test_sse.py b/tests/test_sse.py index 6a9d669fe..fb280b1c3 100644 --- a/tests/test_sse.py +++ b/tests/test_sse.py @@ -264,6 +264,14 @@ def test_data_and_raw_data_mutually_exclusive(): ServerSentEvent(data="json", raw_data="raw") +def test_format_sse_event_empty_data_str(): + """An empty data payload must still emit a single `data:` field and the + `\\n\\n` event terminator (`"".splitlines()` would otherwise drop it).""" + from fastapi.sse import format_sse_event + + assert format_sse_event(data_str="") == b"data: \n\n" + + def test_sse_on_router_included_in_app(client: TestClient): response = client.get("/api/events") assert response.status_code == 200