Browse Source

feat(middleware): expose BaseHTTPMiddleware directly from fastapi.middleware.base

docs(middleware): add multiple-file custom middleware example
pull/14173/head
Santosh Bhandari 9 months ago
parent
commit
9aa48f38da
  1. 35
      docs/en/docs/tutorial/middleware.md
  2. 0
      docs_src/middleware/tutorial002/__init__.py
  3. 7
      docs_src/middleware/tutorial002/main.py
  4. 17
      docs_src/middleware/tutorial002/middleware.py
  5. 3
      fastapi/middleware/base.py

35
docs/en/docs/tutorial/middleware.md

@ -65,6 +65,41 @@ Here we use <a href="https://docs.python.org/3/library/time.html#time.perf_count
///
### Multiple-File Custom Middleware Example { #custom-middleware-multiple-files }
In larger applications, it's often cleaner to keep your middleware code in a separate module instead of defining it directly in your `main.py`.
For example, you could create a new file called `middleware.py` with the following content:
{* ../../docs_src/middleware/tutorial002/middleware.py hl[4,7:9,12,14] *}
Here, we define a class `ProcessTimeHeaderMiddleware` that inherits from `BaseHTTPMiddleware`.
This middleware measures how long each request takes to be processed and adds a custom header to the response.
Then, in your main application file, you can import and use the middleware as follows:
{* ../../docs_src/middleware/tutorial002/main.py hl[7] *}
In this example:
* The middleware is imported from `middleware.py`.
* It’s added to the FastAPI application using `app.add_middleware(...)`.
* Each incoming request is timed, and the processing duration is added as a header named `X-Process-Time`.
/// tip
Separating your middleware into its own module helps organize code for larger projects and keeps `main.py` clean and maintainable.
///
/// note | Technical Details
You could also use `from starlette.middleware.base import BaseHTTPMiddleware`.
**FastAPI** provides it as a convenience for developers, but it comes from Starlette.
///
## Multiple middleware execution order { #multiple-middleware-execution-order }
When you add multiple middlewares using either `@app.middleware()` decorator or `app.add_middleware()` method, each new middleware wraps the application, forming a stack. The last middleware added is the *outermost*, and the first is the *innermost*.

0
docs_src/middleware/tutorial002/__init__.py

7
docs_src/middleware/tutorial002/main.py

@ -0,0 +1,7 @@
from fastapi import FastAPI
from .middleware import ProcessTimeHeaderMiddleware
app = FastAPI()
app.add_middleware(ProcessTimeHeaderMiddleware, header_name="X-Process-Time")

17
docs_src/middleware/tutorial002/middleware.py

@ -0,0 +1,17 @@
import time
from fastapi import Request
from fastapi.middleware.base import BaseHTTPMiddleware
class ProcessTimeHeaderMiddleware(BaseHTTPMiddleware):
def __init__(self, app, header_name: str = "X-Process-Time"):
super().__init__(app)
self.header_name = header_name
async def dispatch(self, request: Request, call_next):
start_time = time.perf_counter()
response = await call_next(request)
process_time = time.perf_counter() - start_time
response.headers[self.header_name] = str(process_time)
return response

3
fastapi/middleware/base.py

@ -0,0 +1,3 @@
from starlette.middleware.base import ( # noqa
BaseHTTPMiddleware as BaseHTTPMiddleware,
)
Loading…
Cancel
Save