Skip to content

Commit 1d6161c

Browse files
committed
Update impl
1 parent ccc0f40 commit 1d6161c

3 files changed

Lines changed: 42 additions & 6 deletions

File tree

fastapi/dependencies/utils.py

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -253,22 +253,32 @@ def get_typed_signature(call: Callable[..., Any]) -> inspect.Signature:
253253
name=param.name,
254254
kind=param.kind,
255255
default=param.default,
256-
annotation=get_typed_annotation(param, globalns),
256+
annotation=get_typed_annotation(param.annotation, globalns),
257257
)
258258
for param in signature.parameters.values()
259259
]
260260
typed_signature = inspect.Signature(typed_params)
261261
return typed_signature
262262

263263

264-
def get_typed_annotation(param: inspect.Parameter, globalns: Dict[str, Any]) -> Any:
265-
annotation = param.annotation
264+
def get_typed_annotation(annotation: Any, globalns: Dict[str, Any]) -> Any:
266265
if isinstance(annotation, str):
267266
annotation = ForwardRef(annotation)
268267
annotation = evaluate_forwardref(annotation, globalns, globalns)
269268
return annotation
270269

271270

271+
def get_typed_return_annotation(call: Callable[..., Any]) -> Any:
272+
signature = inspect.signature(call)
273+
annotation = signature.return_annotation
274+
275+
if annotation is inspect.Signature.empty:
276+
return None
277+
278+
globalns = getattr(call, "__globals__", {})
279+
return get_typed_annotation(annotation, globalns)
280+
281+
272282
def get_dependant(
273283
*,
274284
path: str,

fastapi/routing.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
get_body_field,
2626
get_dependant,
2727
get_parameterless_sub_dependant,
28+
get_typed_return_annotation,
2829
solve_dependencies,
2930
)
3031
from fastapi.encoders import DictIntStrAny, SetIntStr, jsonable_encoder
@@ -350,6 +351,8 @@ def __init__(
350351
) -> None:
351352
self.path = path
352353
self.endpoint = endpoint
354+
if response_model is None:
355+
response_model = get_typed_return_annotation(endpoint)
353356
self.response_model = response_model
354357
self.summary = summary
355358
self.response_description = response_description

tests/test_response_model_as_return_annotation.py

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,17 +16,22 @@ class ModelTwo(BaseModel):
1616

1717
@app.get("/valid1")
1818
def valid1() -> ModelOne:
19-
pass
19+
return ModelOne(name="Test")
2020

2121

2222
@app.get("/valid2", response_model=ModelTwo)
2323
def valid2():
24-
pass
24+
return ModelTwo(surname="Test")
2525

2626

2727
@app.get("/valid3", response_model=ModelTwo)
2828
def valid3() -> ModelOne:
29-
pass
29+
return ModelTwo(surname="Test")
30+
31+
32+
@app.get("/valid4")
33+
def valid4() -> "ModelOne":
34+
return ModelOne(name="Test")
3035

3136

3237
openapi_schema = {
@@ -81,6 +86,22 @@ def valid3() -> ModelOne:
8186
},
8287
}
8388
},
89+
"/valid4": {
90+
"get": {
91+
"summary": "Valid4",
92+
"operationId": "valid4_valid4_get",
93+
"responses": {
94+
"200": {
95+
"description": "Successful Response",
96+
"content": {
97+
"application/json": {
98+
"schema": {"$ref": "#/components/schemas/ModelOne"}
99+
}
100+
},
101+
}
102+
},
103+
}
104+
},
84105
},
85106
"components": {
86107
"schemas": {
@@ -116,3 +137,5 @@ def test_path_operations():
116137
assert response.status_code == 200, response.text
117138
response = client.get("/valid3")
118139
assert response.status_code == 200, response.text
140+
response = client.get("/valid4")
141+
assert response.status_code == 200, response.text

0 commit comments

Comments
 (0)