From 1a4d3e4a375a0aecdaed54793a19848f66c646a0 Mon Sep 17 00:00:00 2001 From: Prashanth1602 Date: Mon, 27 Apr 2026 15:23:29 +0530 Subject: [PATCH] Fix: preserve stream_item_type when using include_router for SSE routes --- fastapi/routing.py | 8 ++++++++ tests/test_sse.py | 17 +++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/fastapi/routing.py b/fastapi/routing.py index 36acb6b89d..8275d58b2d 100644 --- a/fastapi/routing.py +++ b/fastapi/routing.py @@ -1794,6 +1794,14 @@ class APIRouter(routing.Router): self.strict_content_type, ), ) + new_route = self.routes[-1] + if ( + isinstance(new_route, APIRoute) + and isinstance(route, APIRoute) + and getattr(route, "stream_item_type", None) is not None + ): + new_route.stream_item_type = route.stream_item_type + elif isinstance(route, routing.Route): methods = list(route.methods or []) self.add_route( diff --git a/tests/test_sse.py b/tests/test_sse.py index 6dfec61838..e86b3970ee 100644 --- a/tests/test_sse.py +++ b/tests/test_sse.py @@ -264,6 +264,23 @@ def test_sse_on_router_included_in_app(client: TestClient): ] assert len(data_lines) == 2 +def test_include_router_copies_stream_item_type(): + sub_router = APIRouter() + + @sub_router.get("/stream_item_type", response_class=EventSourceResponse) + async def stream_item_type_route() -> AsyncIterable[Item]: + yield items[0] + + assert getattr(sub_router.routes[-1], "stream_item_type", None) == Item + + main_app = FastAPI() + main_app.include_router(sub_router) + + route = next(r for r in main_app.routes + if r.path == "/stream_item_type") + assert getattr(route, "stream_item_type", None) == Item + + # Keepalive ping tests