From c37cb1f95b018007ff38c734927859bdc4e9c74a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sondre=20Lilleb=C3=B8=20Gundersen?= Date: Sat, 18 Sep 2021 21:10:42 +0200 Subject: [PATCH 1/8] Include 404 in the set of documented responses --- fastapi_crudrouter/core/_base.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/fastapi_crudrouter/core/_base.py b/fastapi_crudrouter/core/_base.py index 3e3f394..474b215 100644 --- a/fastapi_crudrouter/core/_base.py +++ b/fastapi_crudrouter/core/_base.py @@ -7,6 +7,8 @@ from ._utils import pagination_factory, schema_factory NOT_FOUND = HTTPException(404, "Item not found") +NOT_FOUND_RESPONSE = {"404": {"detail": "Item not found"}} +RESPONSES = NOT_FOUND_RESPONSE # can be extended to contain multiple responses class CRUDGenerator(Generic[T], APIRouter): @@ -90,6 +92,7 @@ def __init__( response_model=self.schema, summary="Get One", dependencies=get_one_route, + responses=RESPONSES, ) if update_route: @@ -100,6 +103,7 @@ def __init__( response_model=self.schema, summary="Update One", dependencies=update_route, + responses=RESPONSES, ) if delete_one_route: @@ -110,6 +114,7 @@ def __init__( response_model=self.schema, summary="Delete One", dependencies=delete_one_route, + responses=RESPONSES, ) def _add_api_route( From f78d96281b19ab22d7b91816f45789351c102169 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sondre=20Lilleb=C3=B8=20Gundersen?= Date: Sat, 18 Sep 2021 21:11:26 +0200 Subject: [PATCH 2/8] Add test --- tests/test_openapi_schema.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/test_openapi_schema.py b/tests/test_openapi_schema.py index 73de040..0908dd0 100644 --- a/tests/test_openapi_schema.py +++ b/tests/test_openapi_schema.py @@ -26,3 +26,9 @@ def test_schema_tags(self, client): for m in method: assert method[m]["tags"] == PATH_TAGS[path] + + def test_response_types(self, client): + schema = self.test_schema_exists(client).json() + assert "200" in schema["paths"]["/potato/{item_id}"]["get"]["responses"] + assert "422" in schema["paths"]["/potato/{item_id}"]["get"]["responses"] + assert "404" in schema["paths"]["/potato/{item_id}"]["get"]["responses"] From afce40d9a2a8ea4836bc4fe9ca04b91ba6013819 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sondre=20Lilleb=C3=B8=20Gundersen?= Date: Sat, 18 Sep 2021 21:11:52 +0200 Subject: [PATCH 3/8] Update CONTRIBUTING.md --- CONTRIBUTING.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 37256bf..48baf0b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,3 +1 @@ - - Pull requests and contributions are welcome. Please read the [contributions guidelines](https://fastapi-crudrouter.awtkns.com/contributing) for more details. From 04a36a97f3659111a56575f448fd1193b5ac300b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sondre=20Lilleb=C3=B8=20Gundersen?= Date: Sat, 18 Sep 2021 21:12:03 +0200 Subject: [PATCH 4/8] Remove unused import --- tests/conftest.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/conftest.py b/tests/conftest.py index af6903f..74ac91a 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,5 +1,4 @@ import pytest -import inspect from fastapi.testclient import TestClient from .implementations import * From eb489bbe45c183208b7eacde4ba59ecd43ae49d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sondre=20Lilleb=C3=B8=20Gundersen?= Date: Sun, 19 Sep 2021 09:14:41 +0200 Subject: [PATCH 5/8] Remove extra response definition --- fastapi_crudrouter/core/_base.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/fastapi_crudrouter/core/_base.py b/fastapi_crudrouter/core/_base.py index 474b215..8f2e8bc 100644 --- a/fastapi_crudrouter/core/_base.py +++ b/fastapi_crudrouter/core/_base.py @@ -7,8 +7,7 @@ from ._utils import pagination_factory, schema_factory NOT_FOUND = HTTPException(404, "Item not found") -NOT_FOUND_RESPONSE = {"404": {"detail": "Item not found"}} -RESPONSES = NOT_FOUND_RESPONSE # can be extended to contain multiple responses +RESPONSES = {"404": {"detail": "Item not found"}} class CRUDGenerator(Generic[T], APIRouter): From 218c6172be063d2d03c79448b1414ec048cdf865 Mon Sep 17 00:00:00 2001 From: awtkns Date: Sun, 19 Sep 2021 11:49:52 -0700 Subject: [PATCH 6/8] :white_check_mark: Generify and Add Additional Tests --- .gitignore | 1 + fastapi_crudrouter/core/_base.py | 18 +++++++++++++----- tests/test_openapi_schema.py | 21 +++++++++++++++++---- 3 files changed, 31 insertions(+), 9 deletions(-) diff --git a/.gitignore b/.gitignore index cd099f5..2679283 100644 --- a/.gitignore +++ b/.gitignore @@ -39,6 +39,7 @@ coverage.xml *.py,cover .hypothesis/ .pytest_cache/ +.mypy_cache/ # Environments .env diff --git a/fastapi_crudrouter/core/_base.py b/fastapi_crudrouter/core/_base.py index 8f2e8bc..e6a4611 100644 --- a/fastapi_crudrouter/core/_base.py +++ b/fastapi_crudrouter/core/_base.py @@ -7,7 +7,6 @@ from ._utils import pagination_factory, schema_factory NOT_FOUND = HTTPException(404, "Item not found") -RESPONSES = {"404": {"detail": "Item not found"}} class CRUDGenerator(Generic[T], APIRouter): @@ -91,7 +90,7 @@ def __init__( response_model=self.schema, summary="Get One", dependencies=get_one_route, - responses=RESPONSES, + error_responses=[NOT_FOUND], ) if update_route: @@ -102,7 +101,7 @@ def __init__( response_model=self.schema, summary="Update One", dependencies=update_route, - responses=RESPONSES, + error_responses=[NOT_FOUND], ) if delete_one_route: @@ -113,7 +112,7 @@ def __init__( response_model=self.schema, summary="Delete One", dependencies=delete_one_route, - responses=RESPONSES, + error_responses=[NOT_FOUND], ) def _add_api_route( @@ -121,10 +120,19 @@ def _add_api_route( path: str, endpoint: Callable[..., Any], dependencies: Union[bool, DEPENDENCIES], + error_responses: Any = None, **kwargs: Any, ) -> None: dependencies = [] if isinstance(dependencies, bool) else dependencies - super().add_api_route(path, endpoint, dependencies=dependencies, **kwargs) + responses = ( + {err.status_code: {"detail": err.detail} for err in error_responses} + if error_responses + else None + ) + + super().add_api_route( + path, endpoint, dependencies=dependencies, responses=responses, **kwargs + ) def api_route( self, path: str, *args: Any, **kwargs: Any diff --git a/tests/test_openapi_schema.py b/tests/test_openapi_schema.py index 0908dd0..61faf75 100644 --- a/tests/test_openapi_schema.py +++ b/tests/test_openapi_schema.py @@ -1,6 +1,9 @@ +from pytest import mark + from tests import CUSTOM_TAGS POTATO_TAGS = ["Potato"] +PATHS = ["/potato", "/carrot"] PATH_TAGS = { "/potato": POTATO_TAGS, "/potato/{item_id}": POTATO_TAGS, @@ -27,8 +30,18 @@ def test_schema_tags(self, client): for m in method: assert method[m]["tags"] == PATH_TAGS[path] - def test_response_types(self, client): + @mark.parametrize("path", PATHS) + def test_response_types(self, client, path): schema = self.test_schema_exists(client).json() - assert "200" in schema["paths"]["/potato/{item_id}"]["get"]["responses"] - assert "422" in schema["paths"]["/potato/{item_id}"]["get"]["responses"] - assert "404" in schema["paths"]["/potato/{item_id}"]["get"]["responses"] + paths = schema["paths"] + + for method in ["get", "post", "delete"]: + assert "200" in paths[path][method]["responses"] + + assert "422" in paths[path]["post"]["responses"] + + item_path = path + "/{item_id}" + for method in ["get", "put", "delete"]: + assert "200" in paths[item_path][method]["responses"] + assert "404" in paths[item_path][method]["responses"] + assert "422" in paths[item_path][method]["responses"] From 8d41fe38e60a30e3c398b70957443075b48c7991 Mon Sep 17 00:00:00 2001 From: awtkns Date: Sun, 19 Sep 2021 11:59:54 -0700 Subject: [PATCH 7/8] :bookmark: Bump Version to 0.8.3 releasing #104 --- fastapi_crudrouter/_version.py | 2 +- fastapi_crudrouter/core/_base.py | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/fastapi_crudrouter/_version.py b/fastapi_crudrouter/_version.py index deded32..732155f 100644 --- a/fastapi_crudrouter/_version.py +++ b/fastapi_crudrouter/_version.py @@ -1 +1 @@ -__version__ = "0.8.2" +__version__ = "0.8.3" diff --git a/fastapi_crudrouter/core/_base.py b/fastapi_crudrouter/core/_base.py index e6a4611..93899b5 100644 --- a/fastapi_crudrouter/core/_base.py +++ b/fastapi_crudrouter/core/_base.py @@ -1,4 +1,4 @@ -from typing import Any, Callable, Generic, List, Optional, Type, Union +from typing import Any, Callable, Generic, List, Optional, Type, Union, Dict from fastapi import APIRouter, HTTPException from fastapi.types import DecoratedCallable @@ -120,11 +120,11 @@ def _add_api_route( path: str, endpoint: Callable[..., Any], dependencies: Union[bool, DEPENDENCIES], - error_responses: Any = None, + error_responses: Optional[List[HTTPException]] = None, **kwargs: Any, ) -> None: dependencies = [] if isinstance(dependencies, bool) else dependencies - responses = ( + responses: Any = ( {err.status_code: {"detail": err.detail} for err in error_responses} if error_responses else None From 3e5c2e73c13af0aeef4971cafcf830deca8a7163 Mon Sep 17 00:00:00 2001 From: awtkns Date: Sun, 19 Sep 2021 12:02:38 -0700 Subject: [PATCH 8/8] :wastebasket: Clean Up Imports --- fastapi_crudrouter/core/_base.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fastapi_crudrouter/core/_base.py b/fastapi_crudrouter/core/_base.py index 93899b5..f6379e8 100644 --- a/fastapi_crudrouter/core/_base.py +++ b/fastapi_crudrouter/core/_base.py @@ -1,4 +1,4 @@ -from typing import Any, Callable, Generic, List, Optional, Type, Union, Dict +from typing import Any, Callable, Generic, List, Optional, Type, Union from fastapi import APIRouter, HTTPException from fastapi.types import DecoratedCallable