From 50d7072aa0428efc4299f324ebd45c1b388d2013 Mon Sep 17 00:00:00 2001 From: Vinay Karanam Date: Fri, 12 Feb 2021 21:14:28 +0530 Subject: [PATCH] Fixed python 3.8.7 compatibility * Upgraded starlette to 0.14.2 * Added UJSONResponse into the project --- fastapi/responses.py | 14 +++++++- pyproject.toml | 3 +- .../test_custom_response/test_tutorial001.py | 36 +++++++++++++++++++ 3 files changed, 51 insertions(+), 2 deletions(-) create mode 100644 tests/test_tutorial/test_custom_response/test_tutorial001.py diff --git a/fastapi/responses.py b/fastapi/responses.py index 8d9d62dfb0068..9895aa5e6fa1d 100644 --- a/fastapi/responses.py +++ b/fastapi/responses.py @@ -7,13 +7,17 @@ from starlette.responses import RedirectResponse as RedirectResponse # noqa from starlette.responses import Response as Response # noqa from starlette.responses import StreamingResponse as StreamingResponse # noqa -from starlette.responses import UJSONResponse as UJSONResponse # noqa try: import orjson except ImportError: # pragma: nocover orjson = None # type: ignore +try: + import ujson +except ImportError: # pragma: nocover + ujson = None # type: ignore + class ORJSONResponse(JSONResponse): media_type = "application/json" @@ -21,3 +25,11 @@ class ORJSONResponse(JSONResponse): def render(self, content: Any) -> bytes: assert orjson is not None, "orjson must be installed to use ORJSONResponse" return orjson.dumps(content) + + +class UJSONResponse(JSONResponse): + media_type = "application/json" + + def render(self, content: Any) -> bytes: + assert ujson is not None, "ujson must be installed to use UJSONResponse" + return ujson.dumps(content, ensure_ascii=False).encode("utf-8") diff --git a/pyproject.toml b/pyproject.toml index 567276036f35e..03483c5d6e63a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -32,7 +32,7 @@ classifiers = [ "Topic :: Internet :: WWW/HTTP", ] requires = [ - "starlette ==0.13.6", + "starlette ==0.14.2", "pydantic >=1.0.0,<2.0.0" ] description-file = "README.md" @@ -56,6 +56,7 @@ test = [ "sqlalchemy >=1.3.18,<2.0.0", "peewee >=3.13.3,<4.0.0", "databases[sqlite] >=0.3.2,<0.4.0", + "ujson >=3.0.0,<4.0.0", "orjson >=3.2.1,<4.0.0", "async_exit_stack >=1.0.1,<2.0.0", "async_generator >=1.10,<2.0.0", diff --git a/tests/test_tutorial/test_custom_response/test_tutorial001.py b/tests/test_tutorial/test_custom_response/test_tutorial001.py new file mode 100644 index 0000000000000..430076f88f0fd --- /dev/null +++ b/tests/test_tutorial/test_custom_response/test_tutorial001.py @@ -0,0 +1,36 @@ +from fastapi.testclient import TestClient + +from docs_src.custom_response.tutorial001 import app + +client = TestClient(app) + +openapi_schema = { + "openapi": "3.0.2", + "info": {"title": "FastAPI", "version": "0.1.0"}, + "paths": { + "/items/": { + "get": { + "responses": { + "200": { + "description": "Successful Response", + "content": {"application/json": {"schema": {}}}, + } + }, + "summary": "Read Items", + "operationId": "read_items_items__get", + } + } + }, +} + + +def test_openapi_schema(): + response = client.get("/openapi.json") + assert response.status_code == 200, response.text + assert response.json() == openapi_schema + + +def test_get_custom_response(): + response = client.get("/items/") + assert response.status_code == 200, response.text + assert response.json() == [{"item_id": "Foo"}]