Browse Source

Add variants for `custom_request_and_route/tutorial003`

pull/14413/head
Yurii Motov 8 months ago
parent
commit
ff9c332f80
  1. 4
      docs/en/docs/how-to/custom-request-and-route.md
  2. 39
      docs_src/custom_request_and_route/tutorial003_py310.py
  3. 23
      tests/test_tutorial/test_custom_request_and_route/test_tutorial003.py

4
docs/en/docs/how-to/custom-request-and-route.md

@ -102,8 +102,8 @@ If an exception occurs, the`Request` instance will still be in scope, so we can
You can also set the `route_class` parameter of an `APIRouter`:
{* ../../docs_src/custom_request_and_route/tutorial003.py hl[26] *}
{* ../../docs_src/custom_request_and_route/tutorial003_py310.py hl[26] *}
In this example, the *path operations* under the `router` will use the custom `TimedRoute` class, and will have an extra `X-Response-Time` header in the response with the time it took to generate the response:
{* ../../docs_src/custom_request_and_route/tutorial003.py hl[13:20] *}
{* ../../docs_src/custom_request_and_route/tutorial003_py310.py hl[13:20] *}

39
docs_src/custom_request_and_route/tutorial003_py310.py

@ -0,0 +1,39 @@
import time
from collections.abc import Callable
from fastapi import APIRouter, FastAPI, Request, Response
from fastapi.routing import APIRoute
class TimedRoute(APIRoute):
def get_route_handler(self) -> Callable:
original_route_handler = super().get_route_handler()
async def custom_route_handler(request: Request) -> Response:
before = time.time()
response: Response = await original_route_handler(request)
duration = time.time() - before
response.headers["X-Response-Time"] = str(duration)
print(f"route duration: {duration}")
print(f"route response: {response}")
print(f"route response headers: {response.headers}")
return response
return custom_route_handler
app = FastAPI()
router = APIRouter(route_class=TimedRoute)
@app.get("/")
async def not_timed():
return {"message": "Not timed"}
@router.get("/timed")
async def timed():
return {"message": "It's the time of my life"}
app.include_router(router)

23
tests/test_tutorial/test_custom_request_and_route/test_tutorial003.py

@ -1,17 +1,32 @@
import importlib
import pytest
from fastapi.testclient import TestClient
from docs_src.custom_request_and_route.tutorial003 import app
from tests.utils import needs_py310
@pytest.fixture(
name="client",
params=[
pytest.param("tutorial003"),
pytest.param("tutorial003_py310", marks=needs_py310),
],
)
def get_client(request: pytest.FixtureRequest):
mod = importlib.import_module(f"docs_src.custom_request_and_route.{request.param}")
client = TestClient(app)
client = TestClient(mod.app)
return client
def test_get():
def test_get(client: TestClient):
response = client.get("/")
assert response.json() == {"message": "Not timed"}
assert "X-Response-Time" not in response.headers
def test_get_timed():
def test_get_timed(client: TestClient):
response = client.get("/timed")
assert response.json() == {"message": "It's the time of my life"}
assert "X-Response-Time" in response.headers

Loading…
Cancel
Save