Since FastAPI is actually Starlette underneath, you could use BaseHTTPMiddleware, which allows one to implement a middleware class (you may want to have a look at this post as well). Below are given two variants of the same approach on how to do that, where the add_middleware() function is used to add the middleware class (Option 2 might be easier for most users). Please note that it is currently not possible to use BackgroundTasks (if that's a requirement for your task) with BaseHTTPMiddleware—check #1438 and #1640 for more details and any recent updates. Alternatives can be found in this answer and this answer.
Option 1
middlewares.py
from fastapi import Request
class MyMiddleware:
def __init__(self, some_attribute: str):
self.some_attribute = some_attribute
async def __call__(self, request: Request, call_next):
# do something with the request object
content_type = request.headers.get('Content-Type')
print(content_type)
# process the request and get the response
response = await call_next(request)
return response
app.py
from fastapi import FastAPI
from middlewares import MyMiddleware
from starlette.middleware.base import BaseHTTPMiddleware
app = FastAPI()
my_middleware = MyMiddleware(some_attribute="some_attribute_here_if_needed")
app.add_middleware(BaseHTTPMiddleware, dispatch=my_middleware)
Option 2
middlewares.py
from fastapi import Request
from starlette.middleware.base import BaseHTTPMiddleware
class MyMiddleware(BaseHTTPMiddleware):
async def dispatch(self, request: Request, call_next):
# do something with the request object, for example
content_type = request.headers.get('Content-Type')
print(content_type)
# process the request and get the response
response = await call_next(request)
return response
app.py
from fastapi import FastAPI
from middlewares import MyMiddleware
app = FastAPI()
app.add_middleware(MyMiddleware)
If you want to provide configuration options to the middleware class you should override the __init__ method, ensuring that the first argument is app, and any remaining arguments are optional keyword arguments. Example:
middlewares.py
from fastapi import Request
from starlette.middleware.base import BaseHTTPMiddleware
class MyMiddleware(BaseHTTPMiddleware):
def __init__(self, app, some_attribute: str):
super().__init__(app)
self.some_attribute = some_attribute
async def dispatch(self, request: Request, call_next):
# do something with the request object, for example:
content_type = request.headers.get('Content-Type')
print(content_type)
# process the request and get the response
response = await call_next(request)
# add new header to the response
response.headers['Custom'] = self.some_attribute
return response
app.py
from fastapi import FastAPI
from middlewares import MyMiddleware
app = FastAPI()
app.add_middleware(MyMiddleware, some_attribute="some_attribute_here_if_needed")