Middlewares¶
A middleware adds a behaviour to every request, they go between the app and the handler. You can use the included middlewares or create your own.
Create your own middleware¶
Class based middleware¶
To make a middleware, you can subclass the Middleware
and define the
__call__
method.
This method must be an asynchronous method that takes a Request
argument and returns a Response
.
To call the next middleware, you can use self.next
with await self.next(request)
.
For example, a middleware that would time the request:
1 2 3 4 5 6 7 8 9 10 11 12 13 | import time
from baguette import Middleware
class TimingMiddleware(Middleware):
async def __call__(self, request: Request):
start_time = time.perf_counter()
response = await self.next(request)
print(
"{0.method} {0.path} took {1} seconds to be handled".format(
request, time.perf_counter() - start_time
)
)
return response
|
To add that middleware to the application you have 3 ways to do it:
With the
@app.middleware
decorator:app = Baguette() @app.middleware() class TimingMiddleware: ...
With the
middleware
parameter inBaguette
:app = Baguette(middlewares=[TimingMiddleware])
With the
app.add_middleware
method:app = Baguette() app.add_middleware(TimingMiddleware)
Function based middleware¶
You can also write middlewares in functions for simpler middlewares. The function must have 2 parameters: the next middleware to call and the request.
For example, the same timing middleware with a function would look like this:
1 2 3 4 5 6 7 8 9 10 11 12 | import time
@app.middleware()
async def timing_middleware(next_middleware, request):
start_time = time.perf_counter()
response = await next_middleware(request)
print(
"{0.method} {0.path} took {1} seconds to be handled".format(
request, time.perf_counter() - start_time
)
)
return response
|
Default middlewares¶
There are some middlewares that are in the middleware stack by default. The middleware stack will be like this:
Your custom middlewares
Editing requests and reponses¶
Middlewares usually edit the request and reponse.
In the Request
, you can’t edit the Request.body()
method and the
other methods of the request body because they are methods and not attributes.
However there are some methods to remedy to this issue:
Request.set_raw_body()
, Request.set_body()
, Request.set_json()
and Request.set_form()
.
For Response
, it is easier: you can just set the Response.body
to the new response body, or for a JSONResponse
you can edit the
JSONResponse.json
. The only exception is for FileResponse
, if
you want to change the file, you need to create a new FileResponse
.