fix(api): encode untyped datetime responses

This commit is contained in:
2026-07-31 18:39:36 +08:00
parent 3dfb9cd56f
commit c7799e951a
2 changed files with 53 additions and 0 deletions
+20
View File
@@ -8,8 +8,10 @@ from functools import wraps
from typing import Any, Generic, TypeVar, get_args, get_origin
from fastapi import APIRouter, Depends, Query
from fastapi.encoders import jsonable_encoder
from fastapi.routing import APIRoute
from pydantic import BaseModel, JsonValue, create_model
from starlette.responses import Response
from app.api.problem_details import ProblemDetails
from app.api.v1.router import api_router as handler_api_router
@@ -263,6 +265,21 @@ def _with_pagination(endpoint):
return wrapper
def _with_jsonable_response(endpoint):
"""Normalize untyped handler results before JsonValue validation."""
@wraps(endpoint)
async def wrapper(*args, **kwargs):
result = endpoint(*args, **kwargs)
if inspect.isawaitable(result):
result = await result
if isinstance(result, Response):
return result
return jsonable_encoder(result)
return wrapper
def _adapt_route(route: APIRoute) -> APIRoute:
methods = route.methods or set()
if len(methods) != 1:
@@ -286,6 +303,9 @@ def _adapt_route(route: APIRoute) -> APIRoute:
endpoint = _with_header_project_context(route.endpoint, route.name)
response_model = route.response_model
has_untyped_response = response_model is None
if has_untyped_response:
endpoint = _with_jsonable_response(endpoint)
if get_origin(response_model) is list:
item_type = get_args(response_model)[0] if get_args(response_model) else JsonValue
response_model = Page[item_type]