Auto-mount fragment handlers: eliminate fragment blueprint boilerplate across all 8 services
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 16m38s
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 16m38s
Fragment read API is now fully declarative — every handler is a defhandler s-expression dispatched through one shared auto_mount_fragment_handlers() function. Replaces 8 near-identical blueprint files (~35 lines each) with a single function call per service. Events Python handlers (container-cards, account-page) extracted to a standalone module. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -204,3 +204,42 @@ def create_handler_blueprint(service_name: str) -> Any:
|
||||
bp._python_handlers = _python_handlers # type: ignore[attr-defined]
|
||||
|
||||
return bp
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Direct app mount — replaces per-service fragment blueprint boilerplate
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
def auto_mount_fragment_handlers(app: Any, service_name: str) -> Callable:
|
||||
"""Mount ``/internal/fragments/<type>`` directly on the app.
|
||||
|
||||
Returns an ``add_handler(name, fn, content_type)`` function for
|
||||
registering Python handler overrides (checked before SX handlers).
|
||||
"""
|
||||
from quart import Response, request
|
||||
from shared.infrastructure.fragments import FRAGMENT_HEADER
|
||||
|
||||
python_handlers: dict[str, Callable[[], Awaitable[str]]] = {}
|
||||
html_types: set[str] = set()
|
||||
|
||||
@app.get("/internal/fragments/<fragment_type>")
|
||||
async def _fragment_dispatch(fragment_type: str):
|
||||
if not request.headers.get(FRAGMENT_HEADER):
|
||||
return Response("", status=403)
|
||||
py = python_handlers.get(fragment_type)
|
||||
if py is not None:
|
||||
result = await py()
|
||||
ct = "text/html" if fragment_type in html_types else "text/sx"
|
||||
return Response(result, status=200, content_type=ct)
|
||||
hdef = get_handler(service_name, fragment_type)
|
||||
if hdef is not None:
|
||||
result = await execute_handler(hdef, service_name, args=dict(request.args))
|
||||
return Response(result, status=200, content_type="text/sx")
|
||||
return Response("", status=200, content_type="text/sx")
|
||||
|
||||
def add_handler(name: str, fn: Callable[[], Awaitable[str]], content_type: str = "text/sx") -> None:
|
||||
python_handlers[name] = fn
|
||||
if content_type == "text/html":
|
||||
html_types.add(name)
|
||||
|
||||
return add_handler
|
||||
|
||||
Reference in New Issue
Block a user