Within the FastAPI framework:
While request data can certainly be passed around as an argument, I would like to know if it is possible for a function to access information about the current request without being passed an argument.
Disclaimer: I do not think global access to Request data a good practice, and yet I have a use case where it would be very good to be able to do.
A solution provided here defines a context manager, that you can access globally. For each request, you are extracting the relevant information (like headers) & pass it to the context manager.
Since fastapi is built with Starlette, you can use the library starlette-context. It is creating a context
object that you can use without passing it as argument. The main caveat is that you still need to pass a request object to all your routes.
EDIT: In starlette-context==0.3.0
new middleware has been added. Starlette
team started to discourage (here) the use of their BaseHTTPMiddleware
, in particulary for StreamingResponse/FileResponse endpoints. You might want to use RawContextMiddleware
which also doesn't require the request object but it's experimental as there is no documentation in Starlette
for writing custom middleware without the interface. But it seems to be working.
Sample code from this lib to illustrate:
import uvicorn
from fastapi import FastAPI
from starlette.requests import Request
from starlette.responses import JSONResponse
from starlette.middleware import Middleware
from starlette_context import context, plugins
from starlette_context.middleware import ContextMiddleware
middleware = [
Middleware(
ContextMiddleware,
plugins=(
plugins.RequestIdPlugin(),
plugins.CorrelationIdPlugin()
)
)
]
app = FastAPI(debug=True, middleware=middleware)
@app.route('/')
async def index(request: Request): # This argument is still needed here
return JSONResponse(context.data) # Your context data
uvicorn.run(app, host="0.0.0.0")
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With