Files
ai-agent/backend/core/http.py
Gabriel Vidal 68a3206641 Merge branch 'main' into split-big-files
# Conflicts:
#	backend/main.py
#	backend/schemas.py
#	sidecar/sidecar.py
#	sidecar/test_claude_args.py
2026-10-06 23:57:03 +02:00

41 lines
1.6 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""Route helpers: OpenAPI response-schema attachment and worker-thread JSON."""
import functools
from fastapi.responses import JSONResponse
def _r(model) -> dict:
"""Attach a response schema to a route for OpenAPI/codegen **only**.
Passed as ``responses=`` (not ``response_model=``) so FastAPI documents the
200 body in ``/openapi.json`` — which Orval turns into the frontend's types —
without validating or filtering the handler's actual return value. See
``schemas/``."""
return {200: {"model": model}}
def _json_in_worker(fn):
"""Serialize a heavy sync GET's body inside its worker thread.
A handler returning a plain dict is encoded by FastAPI's pure-Python
``jsonable_encoder`` **on the event loop**, after the threadpool hands the
value back — 5-10× slower than ``json.dumps`` (the full conversation list:
~430 ms vs ~70 ms), and while it runs nothing else is served, not even
``/api/health``. Returning a ready ``JSONResponse`` from the handler moves
that work onto the worker thread. A body ``json.dumps`` can't encode
(a set, a model, a NaN) falls back to FastAPI's encoder unchanged.
Only for plain ``@app.get`` handlers with the default 200 status and no
``Response`` parameter — a returned response replaces both."""
@functools.wraps(fn)
def wrapper(*args, **kwargs):
out = fn(*args, **kwargs)
if isinstance(out, (dict, list)):
try:
return JSONResponse(out)
except (TypeError, ValueError):
return out
return out
return wrapper