mirror of https://github.com/tiangolo/fastapi.git
🐛 Fix preserving route_class when calling include_router (#538)
This commit is contained in:
parent
fdb6d43e10
commit
dd963511d6
|
|
@ -348,8 +348,10 @@ class APIRouter(routing.Router):
|
||||||
include_in_schema: bool = True,
|
include_in_schema: bool = True,
|
||||||
response_class: Type[Response] = None,
|
response_class: Type[Response] = None,
|
||||||
name: str = None,
|
name: str = None,
|
||||||
|
route_class_override: Optional[Type[APIRoute]] = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
route = self.route_class(
|
route_class = route_class_override or self.route_class
|
||||||
|
route = route_class(
|
||||||
path,
|
path,
|
||||||
endpoint=endpoint,
|
endpoint=endpoint,
|
||||||
response_model=response_model,
|
response_model=response_model,
|
||||||
|
|
@ -487,6 +489,7 @@ class APIRouter(routing.Router):
|
||||||
include_in_schema=route.include_in_schema,
|
include_in_schema=route.include_in_schema,
|
||||||
response_class=route.response_class or default_response_class,
|
response_class=route.response_class or default_response_class,
|
||||||
name=route.name,
|
name=route.name,
|
||||||
|
route_class_override=type(route),
|
||||||
)
|
)
|
||||||
elif isinstance(route, routing.Route):
|
elif isinstance(route, routing.Route):
|
||||||
self.add_route(
|
self.add_route(
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,114 @@
|
||||||
|
import pytest
|
||||||
|
from fastapi import APIRouter, FastAPI
|
||||||
|
from fastapi.routing import APIRoute
|
||||||
|
from starlette.testclient import TestClient
|
||||||
|
|
||||||
|
app = FastAPI()
|
||||||
|
|
||||||
|
|
||||||
|
class APIRouteA(APIRoute):
|
||||||
|
x_type = "A"
|
||||||
|
|
||||||
|
|
||||||
|
class APIRouteB(APIRoute):
|
||||||
|
x_type = "B"
|
||||||
|
|
||||||
|
|
||||||
|
class APIRouteC(APIRoute):
|
||||||
|
x_type = "C"
|
||||||
|
|
||||||
|
|
||||||
|
router_a = APIRouter(route_class=APIRouteA)
|
||||||
|
router_b = APIRouter(route_class=APIRouteB)
|
||||||
|
router_c = APIRouter(route_class=APIRouteC)
|
||||||
|
|
||||||
|
|
||||||
|
@router_a.get("/")
|
||||||
|
def get_a():
|
||||||
|
return {"msg": "A"}
|
||||||
|
|
||||||
|
|
||||||
|
@router_b.get("/")
|
||||||
|
def get_b():
|
||||||
|
return {"msg": "B"}
|
||||||
|
|
||||||
|
|
||||||
|
@router_c.get("/")
|
||||||
|
def get_c():
|
||||||
|
return {"msg": "C"}
|
||||||
|
|
||||||
|
|
||||||
|
router_b.include_router(router=router_c, prefix="/c")
|
||||||
|
router_a.include_router(router=router_b, prefix="/b")
|
||||||
|
app.include_router(router=router_a, prefix="/a")
|
||||||
|
|
||||||
|
|
||||||
|
client = TestClient(app)
|
||||||
|
|
||||||
|
openapi_schema = {
|
||||||
|
"openapi": "3.0.2",
|
||||||
|
"info": {"title": "Fast API", "version": "0.1.0"},
|
||||||
|
"paths": {
|
||||||
|
"/a/": {
|
||||||
|
"get": {
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "Successful Response",
|
||||||
|
"content": {"application/json": {"schema": {}}},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"summary": "Get A",
|
||||||
|
"operationId": "get_a_a__get",
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/a/b/": {
|
||||||
|
"get": {
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "Successful Response",
|
||||||
|
"content": {"application/json": {"schema": {}}},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"summary": "Get B",
|
||||||
|
"operationId": "get_b_a_b__get",
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/a/b/c/": {
|
||||||
|
"get": {
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "Successful Response",
|
||||||
|
"content": {"application/json": {"schema": {}}},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"summary": "Get C",
|
||||||
|
"operationId": "get_c_a_b_c__get",
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"path,expected_status,expected_response",
|
||||||
|
[
|
||||||
|
("/a", 200, {"msg": "A"}),
|
||||||
|
("/a/b", 200, {"msg": "B"}),
|
||||||
|
("/a/b/c", 200, {"msg": "C"}),
|
||||||
|
("/openapi.json", 200, openapi_schema),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
def test_get_path(path, expected_status, expected_response):
|
||||||
|
response = client.get(path)
|
||||||
|
assert response.status_code == expected_status
|
||||||
|
assert response.json() == expected_response
|
||||||
|
|
||||||
|
|
||||||
|
def test_route_classes():
|
||||||
|
routes = {}
|
||||||
|
r: APIRoute
|
||||||
|
for r in app.router.routes:
|
||||||
|
routes[r.path] = r
|
||||||
|
assert routes["/a/"].x_type == "A"
|
||||||
|
assert routes["/a/b/"].x_type == "B"
|
||||||
|
assert routes["/a/b/c/"].x_type == "C"
|
||||||
Loading…
Reference in New Issue