Enhance response model inference in APIRoute and utils

- Introduced a new helper function `_contains_response` to check for response types in return annotations, improving the inference logic in `APIRoute`.
- Updated the `infer_response_model_from_ast` function to prevent model creation when all fields are of type `Any`, ensuring better type information and avoiding unnecessary overrides.
This commit is contained in:
g7azazlo 2025-12-03 23:26:27 +03:00
parent 65a9b03c57
commit 7e36726baa
2 changed files with 23 additions and 1 deletions

View File

@ -21,6 +21,8 @@ from typing import (
Tuple,
Type,
Union,
get_args,
get_origin,
)
from annotated_doc import Doc
@ -122,6 +124,18 @@ def request_response(
return app
def _contains_response(annotation: Any) -> bool:
if lenient_issubclass(annotation, Response):
return True
args = get_args(annotation)
for arg in args:
if _contains_response(arg):
return True
return False
# Copy of starlette.routing.websocket_session modified to include the
# dependencies' AsyncExitStack
def websocket_session(
@ -549,7 +563,9 @@ class APIRoute(routing.Route):
not lenient_issubclass(response_model, BaseModel)
and not dataclasses.is_dataclass(response_model)
):
if return_annotation is not None:
if return_annotation is not None and not _contains_response(
return_annotation
):
inferred = infer_response_model_from_ast(endpoint)
if inferred:
response_model = inferred

View File

@ -429,6 +429,12 @@ def infer_response_model_from_ast(
if not fields:
return None
# Don't create a model if all fields are Any - this provides no additional
# type information compared to Dict[str, Any] and would override explicit
# type annotations unnecessarily
if all(field_type is Any for field_type, _ in fields.values()):
return None
if PYDANTIC_V2:
from pydantic import create_model
else: