mirror of
https://github.com/fastapi/fastapi.git
synced 2026-09-12 21:38:39 -04:00
👷 Add OpenAPI dependency benchmarks (#16075)
This commit is contained in:
1 parent
bcd4e895e1
commit
3d3c6913e8
3 files changed
+117
No files matched your search
@@ -0,0 +1,33 @@
|
||||
import sys
|
||||
|
||||
import pytest
|
||||
|
||||
from tests.benchmarks.utils import (
|
||||
ROUTE_COUNT,
|
||||
ROUTE_PATH_PREFIX,
|
||||
create_openapi_app,
|
||||
generate_openapi,
|
||||
)
|
||||
|
||||
if "--codspeed" not in sys.argv:
|
||||
pytest.skip(
|
||||
"Benchmark tests are skipped by default; run with --codspeed.",
|
||||
allow_module_level=True,
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.timeout(60)
|
||||
def test_openapi_dependency_graph(benchmark) -> None:
|
||||
app = create_openapi_app()
|
||||
schema = benchmark(generate_openapi, app)
|
||||
dynamic_paths = [
|
||||
path for path in schema["paths"] if path.startswith(ROUTE_PATH_PREFIX)
|
||||
]
|
||||
assert len(dynamic_paths) == ROUTE_COUNT
|
||||
assert all(
|
||||
any(
|
||||
parameter["in"] == "query" and parameter["name"] == "query_value"
|
||||
for parameter in schema["paths"][path]["get"]["parameters"]
|
||||
)
|
||||
for path in dynamic_paths
|
||||
)
|
||||
@@ -0,0 +1,51 @@
|
||||
from collections.abc import Callable
|
||||
from typing import Annotated, Any
|
||||
|
||||
from fastapi import Depends, FastAPI
|
||||
|
||||
LAST_DEPENDENCY_INDEX = 100
|
||||
ROUTE_COUNT = 20
|
||||
ROUTE_PATH_PREFIX = "/openapi-route-"
|
||||
|
||||
|
||||
def create_openapi_app() -> FastAPI:
|
||||
app = FastAPI()
|
||||
dependencies: dict[int, Callable[..., Any]] = {}
|
||||
|
||||
def create_dependency(index: int) -> Callable[..., Any]:
|
||||
if index == LAST_DEPENDENCY_INDEX:
|
||||
|
||||
def dependency(query_value: int = index) -> str:
|
||||
return str(query_value)
|
||||
|
||||
dependency.__name__ = f"dependency_{index}"
|
||||
return dependency
|
||||
|
||||
next_dependency = dependencies[index + 1]
|
||||
|
||||
async def dependency(
|
||||
sub_dependency: Annotated[str, Depends(next_dependency)],
|
||||
query_value: int = index,
|
||||
) -> str:
|
||||
return f"{query_value} -> {sub_dependency}"
|
||||
|
||||
dependency.__name__ = f"dependency_{index}"
|
||||
return dependency
|
||||
|
||||
for index in reversed(range(LAST_DEPENDENCY_INDEX + 1)):
|
||||
dependencies[index] = create_dependency(index)
|
||||
|
||||
async def endpoint(
|
||||
value: Annotated[str, Depends(dependencies[0])],
|
||||
) -> dict[str, str]:
|
||||
return {"value": value}
|
||||
|
||||
for index in range(ROUTE_COUNT):
|
||||
app.add_api_route(f"{ROUTE_PATH_PREFIX}{index}", endpoint, methods=["GET"])
|
||||
|
||||
return app
|
||||
|
||||
|
||||
def generate_openapi(app: FastAPI) -> dict[str, Any]:
|
||||
app.openapi_schema = None
|
||||
return app.openapi()
|
||||
@@ -0,0 +1,33 @@
|
||||
import sys
|
||||
|
||||
import pytest
|
||||
|
||||
from tests.benchmarks.utils import (
|
||||
ROUTE_COUNT,
|
||||
ROUTE_PATH_PREFIX,
|
||||
create_openapi_app,
|
||||
generate_openapi,
|
||||
)
|
||||
|
||||
if "--codspeed" not in sys.argv:
|
||||
pytest.skip(
|
||||
"Benchmark tests are skipped by default; run with --codspeed.",
|
||||
allow_module_level=True,
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.timeout(60)
|
||||
def test_openapi_dependency_graph(benchmark) -> None:
|
||||
app = create_openapi_app()
|
||||
schema = benchmark(generate_openapi, app)
|
||||
dynamic_paths = [
|
||||
path for path in schema["paths"] if path.startswith(ROUTE_PATH_PREFIX)
|
||||
]
|
||||
assert len(dynamic_paths) == ROUTE_COUNT
|
||||
assert all(
|
||||
any(
|
||||
parameter["in"] == "query" and parameter["name"] == "query_value"
|
||||
for parameter in schema["paths"][path]["get"]["parameters"]
|
||||
)
|
||||
for path in dynamic_paths
|
||||
)
|
||||
Reference in new issue
Block a user