From fa70c5f297ad2c0abe3453c6327da1f9f7ab8379 Mon Sep 17 00:00:00 2001 From: giles Date: Sat, 7 Mar 2026 18:18:28 +0000 Subject: [PATCH] Fix streaming demo: preserve app context across async generator yields Quart's ASGI layer doesn't propagate request/app context into async generator iterations. Wrap execute_page_streaming with stream_with_context so current_app and request remain accessible after each yield. Co-Authored-By: Claude Opus 4.6 --- shared/sx/pages.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/shared/sx/pages.py b/shared/sx/pages.py index e9729b7..f6654fc 100644 --- a/shared/sx/pages.py +++ b/shared/sx/pages.py @@ -507,7 +507,7 @@ def mount_pages(bp: Any, service_name: str, def _mount_one_page(bp: Any, service_name: str, page_def: PageDef) -> None: """Mount a single PageDef as a GET route on the blueprint.""" - from quart import make_response, Response + from quart import make_response, Response, stream_with_context if page_def.stream: # Streaming response: yields HTML chunks as IO resolves @@ -520,9 +520,10 @@ def _mount_one_page(bp: Any, service_name: str, page_def: PageDef) -> None: if hasattr(result, "status_code"): return result return await make_response(result, 200) - # Streaming response + # Streaming response — stream_with_context preserves app/request + # context across async generator yields gen = execute_page_streaming(current, service_name, url_params=kwargs) - return Response(gen, content_type="text/html; charset=utf-8") + return Response(stream_with_context(gen), content_type="text/html; charset=utf-8") else: # Standard non-streaming response async def page_view(**kwargs: Any) -> Any: