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:

  1. With the @app.middleware decorator:

    app = Baguette()
    
    @app.middleware()
    class TimingMiddleware:
        ...
    
  2. With the middleware parameter in Baguette:

    app = Baguette(middlewares=[TimingMiddleware])
    
  3. 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:

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.