From 5892a1d1123cdb38779a0b68e1ffbb27a77d30b0 Mon Sep 17 00:00:00 2001 From: Thomas Meckel Date: Wed, 7 Sep 2022 17:57:10 +0200 Subject: [PATCH 1/4] Fix bug in get_request_handler (fastapi/routing.py) which cleared reponse content because wrong status code variable has been checked --- fastapi/routing.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fastapi/routing.py b/fastapi/routing.py index 233f79fcbf126..710cb97346127 100644 --- a/fastapi/routing.py +++ b/fastapi/routing.py @@ -258,7 +258,7 @@ async def app(request: Request) -> Response: is_coroutine=is_coroutine, ) response = actual_response_class(content, **response_args) - if not is_body_allowed_for_status_code(status_code): + if not is_body_allowed_for_status_code(response.status_code): response.body = b"" response.headers.raw.extend(sub_response.headers.raw) return response From 0dbc75c1f27fdbb75e56abec6a5ec049cb1ec0b0 Mon Sep 17 00:00:00 2001 From: Thomas Meckel Date: Wed, 7 Sep 2022 18:20:27 +0200 Subject: [PATCH 2/4] Added tests/test_reponse_set_reponse_code.py --- tests/test_reponse_set_reponse_code.py | 31 ++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 tests/test_reponse_set_reponse_code.py diff --git a/tests/test_reponse_set_reponse_code.py b/tests/test_reponse_set_reponse_code.py new file mode 100644 index 0000000000000..72595ce51201d --- /dev/null +++ b/tests/test_reponse_set_reponse_code.py @@ -0,0 +1,31 @@ +from fastapi import Depends, FastAPI, Response +from fastapi.params import Path +from fastapi.testclient import TestClient + +msg = {"msg": "Status overwritten"} + +app = FastAPI() + + +@app.delete( + "/{id}", + responses={ + 204: {"model": None, "description": "No Content"}, + }, + status_code=204, +) +async def delete_deployment( + id: str = Path(None), + response: Response = None, +) -> None: + response.status_code = 400 + return msg + + +client = TestClient(app) + + +def test_dependency_set_status_code(): + response = client.delete("/1") + assert response.status_code == 400 and response.content + assert response.json() == msg From 834bb6d48de8e84d3d7b1f522322029b8fafd44c Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 7 Sep 2022 16:29:27 +0000 Subject: [PATCH 3/4] =?UTF-8?q?=F0=9F=8E=A8=20[pre-commit.ci]=20Auto=20for?= =?UTF-8?q?mat=20from=20pre-commit.com=20hooks?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/test_reponse_set_reponse_code.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_reponse_set_reponse_code.py b/tests/test_reponse_set_reponse_code.py index 72595ce51201d..b462d6038fbd2 100644 --- a/tests/test_reponse_set_reponse_code.py +++ b/tests/test_reponse_set_reponse_code.py @@ -1,4 +1,4 @@ -from fastapi import Depends, FastAPI, Response +from fastapi import FastAPI, Response from fastapi.params import Path from fastapi.testclient import TestClient From 9bf2b96ab01ced2a039ebf2e71aa9c9f86389e7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebasti=C3=A1n=20Ram=C3=ADrez?= Date: Thu, 8 Sep 2022 16:58:25 +0200 Subject: [PATCH 4/4] =?UTF-8?q?=E2=9C=85=20Tweak=20and=20simplify=20tests,?= =?UTF-8?q?=20add=20tests=20for=20OpenAPI?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/test_reponse_set_reponse_code.py | 31 ------- tests/test_reponse_set_reponse_code_empty.py | 97 ++++++++++++++++++++ 2 files changed, 97 insertions(+), 31 deletions(-) delete mode 100644 tests/test_reponse_set_reponse_code.py create mode 100644 tests/test_reponse_set_reponse_code_empty.py diff --git a/tests/test_reponse_set_reponse_code.py b/tests/test_reponse_set_reponse_code.py deleted file mode 100644 index b462d6038fbd2..0000000000000 --- a/tests/test_reponse_set_reponse_code.py +++ /dev/null @@ -1,31 +0,0 @@ -from fastapi import FastAPI, Response -from fastapi.params import Path -from fastapi.testclient import TestClient - -msg = {"msg": "Status overwritten"} - -app = FastAPI() - - -@app.delete( - "/{id}", - responses={ - 204: {"model": None, "description": "No Content"}, - }, - status_code=204, -) -async def delete_deployment( - id: str = Path(None), - response: Response = None, -) -> None: - response.status_code = 400 - return msg - - -client = TestClient(app) - - -def test_dependency_set_status_code(): - response = client.delete("/1") - assert response.status_code == 400 and response.content - assert response.json() == msg diff --git a/tests/test_reponse_set_reponse_code_empty.py b/tests/test_reponse_set_reponse_code_empty.py new file mode 100644 index 0000000000000..094d54a84b60c --- /dev/null +++ b/tests/test_reponse_set_reponse_code_empty.py @@ -0,0 +1,97 @@ +from typing import Any + +from fastapi import FastAPI, Response +from fastapi.testclient import TestClient + +app = FastAPI() + + +@app.delete( + "/{id}", + status_code=204, +) +async def delete_deployment( + id: int, + response: Response, +) -> Any: + response.status_code = 400 + return {"msg": "Status overwritten", "id": id} + + +client = TestClient(app) + + +openapi_schema = { + "openapi": "3.0.2", + "info": {"title": "FastAPI", "version": "0.1.0"}, + "paths": { + "/{id}": { + "delete": { + "summary": "Delete Deployment", + "operationId": "delete_deployment__id__delete", + "parameters": [ + { + "required": True, + "schema": {"title": "Id", "type": "integer"}, + "name": "id", + "in": "path", + } + ], + "responses": { + "204": {"description": "Successful Response"}, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + }, + }, + }, + } + } + }, + "components": { + "schemas": { + "HTTPValidationError": { + "title": "HTTPValidationError", + "type": "object", + "properties": { + "detail": { + "title": "Detail", + "type": "array", + "items": {"$ref": "#/components/schemas/ValidationError"}, + } + }, + }, + "ValidationError": { + "title": "ValidationError", + "required": ["loc", "msg", "type"], + "type": "object", + "properties": { + "loc": { + "title": "Location", + "type": "array", + "items": {"anyOf": [{"type": "string"}, {"type": "integer"}]}, + }, + "msg": {"title": "Message", "type": "string"}, + "type": {"title": "Error Type", "type": "string"}, + }, + }, + } + }, +} + + +def test_openapi_schema(): + response = client.get("/openapi.json") + assert response.status_code == 200, response.text + assert response.json() == openapi_schema + + +def test_dependency_set_status_code(): + response = client.delete("/1") + assert response.status_code == 400 and response.content + assert response.json() == {"msg": "Status overwritten", "id": 1}