Browse Source

🐛 Ignore Response classes on return annotation (#5855)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
pull/5872/head
Marcelo Trylesinski 2 years ago
committed by GitHub
parent
commit
fba7493042
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 7
      fastapi/routing.py
  2. 47
      tests/test_response_model_as_return_annotation.py

7
fastapi/routing.py

@ -42,6 +42,7 @@ from fastapi.utils import (
from pydantic import BaseModel from pydantic import BaseModel
from pydantic.error_wrappers import ErrorWrapper, ValidationError from pydantic.error_wrappers import ErrorWrapper, ValidationError
from pydantic.fields import ModelField, Undefined from pydantic.fields import ModelField, Undefined
from pydantic.utils import lenient_issubclass
from starlette import routing from starlette import routing
from starlette.concurrency import run_in_threadpool from starlette.concurrency import run_in_threadpool
from starlette.exceptions import HTTPException from starlette.exceptions import HTTPException
@ -356,7 +357,11 @@ class APIRoute(routing.Route):
self.path = path self.path = path
self.endpoint = endpoint self.endpoint = endpoint
if isinstance(response_model, DefaultPlaceholder): if isinstance(response_model, DefaultPlaceholder):
response_model = get_typed_return_annotation(endpoint) return_annotation = get_typed_return_annotation(endpoint)
if lenient_issubclass(return_annotation, Response):
response_model = None
else:
response_model = return_annotation
self.response_model = response_model self.response_model = response_model
self.summary = summary self.summary = summary
self.response_description = response_description self.response_description = response_description

47
tests/test_response_model_as_return_annotation.py

@ -2,6 +2,7 @@ from typing import List, Union
import pytest import pytest
from fastapi import FastAPI from fastapi import FastAPI
from fastapi.responses import JSONResponse, Response
from fastapi.testclient import TestClient from fastapi.testclient import TestClient
from pydantic import BaseModel, ValidationError from pydantic import BaseModel, ValidationError
@ -237,6 +238,16 @@ def no_response_model_annotation_union_return_model2() -> Union[User, Item]:
return Item(name="Foo", price=42.0) return Item(name="Foo", price=42.0)
@app.get("/no_response_model-annotation_response_class")
def no_response_model_annotation_response_class() -> Response:
return Response(content="Foo")
@app.get("/no_response_model-annotation_json_response_class")
def no_response_model_annotation_json_response_class() -> JSONResponse:
return JSONResponse(content={"foo": "bar"})
openapi_schema = { openapi_schema = {
"openapi": "3.0.2", "openapi": "3.0.2",
"info": {"title": "FastAPI", "version": "0.1.0"}, "info": {"title": "FastAPI", "version": "0.1.0"},
@ -789,6 +800,30 @@ openapi_schema = {
}, },
} }
}, },
"/no_response_model-annotation_response_class": {
"get": {
"summary": "No Response Model Annotation Response Class",
"operationId": "no_response_model_annotation_response_class_no_response_model_annotation_response_class_get",
"responses": {
"200": {
"description": "Successful Response",
"content": {"application/json": {"schema": {}}},
}
},
}
},
"/no_response_model-annotation_json_response_class": {
"get": {
"summary": "No Response Model Annotation Json Response Class",
"operationId": "no_response_model_annotation_json_response_class_no_response_model_annotation_json_response_class_get",
"responses": {
"200": {
"description": "Successful Response",
"content": {"application/json": {"schema": {}}},
}
},
}
},
}, },
"components": { "components": {
"schemas": { "schemas": {
@ -1049,3 +1084,15 @@ def test_no_response_model_annotation_union_return_model2():
response = client.get("/no_response_model-annotation_union-return_model2") response = client.get("/no_response_model-annotation_union-return_model2")
assert response.status_code == 200, response.text assert response.status_code == 200, response.text
assert response.json() == {"name": "Foo", "price": 42.0} assert response.json() == {"name": "Foo", "price": 42.0}
def test_no_response_model_annotation_return_class():
response = client.get("/no_response_model-annotation_response_class")
assert response.status_code == 200, response.text
assert response.text == "Foo"
def test_no_response_model_annotation_json_response_class():
response = client.get("/no_response_model-annotation_json_response_class")
assert response.status_code == 200, response.text
assert response.json() == {"foo": "bar"}

Loading…
Cancel
Save