From f0b9f0491c1faf3657ced1c2d3cf0532802aac8d Mon Sep 17 00:00:00 2001 From: yen3 Date: Tue, 9 Feb 2021 19:45:02 +0100 Subject: [PATCH 1/3] Fix routing problem Original Issue: https://github.com/dmontagu/fastapi-utils/issues/154 Credit: WouldYouKindly If we use class-based routing, the cbv causes the double routes. WouldYouKindly solves the problem, but he does not the patch to the repo. I really need the patch for my daily development so I copy his solution to resolve. If it causes anyone feels uncomfortable, I will delete my PR. Sorry for the copy --- fastapi_restful/cbv.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/fastapi_restful/cbv.py b/fastapi_restful/cbv.py index fbcaf35e..d57a0408 100644 --- a/fastapi_restful/cbv.py +++ b/fastapi_restful/cbv.py @@ -86,7 +86,6 @@ def new_init(self: Any, *args: Any, **kwargs: Any) -> None: def _register_endpoints(router: APIRouter, cls: Type[Any], *urls: str) -> None: - cbv_router = APIRouter() function_members = inspect.getmembers(cls, inspect.isfunction) for url in urls: _allocate_routes_by_method_name(router, url, function_members) @@ -107,10 +106,7 @@ def _register_endpoints(router: APIRouter, cls: Type[Any], *urls: str) -> None: if isinstance(route, (Route, WebSocketRoute)) and route.endpoint in functions_set ] for route in cbv_routes: - router.routes.remove(route) _update_cbv_route_endpoint_signature(cls, route) - cbv_router.routes.append(route) - router.include_router(cbv_router) def _allocate_routes_by_method_name(router: APIRouter, url: str, function_members: List[Tuple[str, Any]]) -> None: From 43a899171afc3beb582d63972116adf6d9ead013 Mon Sep 17 00:00:00 2001 From: Yuval Date: Wed, 5 May 2021 22:49:55 +0300 Subject: [PATCH 2/3] Fix prefix kwarg on router being repetitive when using cbv causing '/api' route to become '/api/api' --- fastapi_restful/cbv.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/fastapi_restful/cbv.py b/fastapi_restful/cbv.py index d57a0408..c354ea77 100644 --- a/fastapi_restful/cbv.py +++ b/fastapi_restful/cbv.py @@ -86,6 +86,7 @@ def new_init(self: Any, *args: Any, **kwargs: Any) -> None: def _register_endpoints(router: APIRouter, cls: Type[Any], *urls: str) -> None: + cbv_router = APIRouter() function_members = inspect.getmembers(cls, inspect.isfunction) for url in urls: _allocate_routes_by_method_name(router, url, function_members) @@ -105,8 +106,13 @@ def _register_endpoints(router: APIRouter, cls: Type[Any], *urls: str) -> None: for route in router.routes if isinstance(route, (Route, WebSocketRoute)) and route.endpoint in functions_set ] + prefix_length = len(router.prefix) # Until 'black' would fix an issue which causes PEP8: E203 for route in cbv_routes: + router.routes.remove(route) + route.path = route.path[prefix_length:] _update_cbv_route_endpoint_signature(cls, route) + cbv_router.routes.append(route) + router.include_router(cbv_router) def _allocate_routes_by_method_name(router: APIRouter, url: str, function_members: List[Tuple[str, Any]]) -> None: From 091e1024e8bfe2eeb5e28faf0c67bff900539a64 Mon Sep 17 00:00:00 2001 From: Yuval Date: Wed, 5 May 2021 22:50:23 +0300 Subject: [PATCH 3/3] Add test to check if route construction is done right when using router prefix --- tests/test_cbv.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/tests/test_cbv.py b/tests/test_cbv.py index 0619c3bb..dafd1a5b 100644 --- a/tests/test_cbv.py +++ b/tests/test_cbv.py @@ -82,3 +82,18 @@ def root(self, item_path: str = None, item_query: str = None) -> Any: assert client.get("/items").json() == [] assert client.get("/items/1").json() == {"item_path": "1"} assert client.get("/database/abc").json() == {"item_path": "abc"} + + +def test_prefix() -> None: + router = APIRouter(prefix="/api") + + @cbv(router) + class RootHandler: + @router.get("/item") + def root(self) -> str: + return "hello" + + client = TestClient(router) + response = client.get("/api/item") + assert response.status_code == 200 + assert response.json() == "hello"