This approach may help remove some of the ongoing confusion and errors people are finding with the root path and proxy settings.
The ROOT_PATH solution you implemented works well in FastAPI providing you have the app running on an endpoint that has a fixed root path. I like it.
But when deploying FastAPI on AWS Lambda as I have been doing, AWS uses different root paths depending upon your 'stage name'. Hardcoding ROOT_PATH parameters is not good for portability of course and in fact means I can't run both a /dev and a /prod staging endpoint using the same codebase without having to fiddle with environment variables, which is a bit tricky on AWS Lambda.
As per the ASGI spec, the root_path should be passed in the request event body for each lambda call. When this root_path exists and works, this can be dealt with cleanly by a small piece of middleware that reads the root_path if it exists and dynamically sets the FastAPI root path.
I've tested it and it works, dropping this middleware into the main.py file in FastAPI
@app.middleware("http")
async def set_root_path_for_api_gateway(request: Request, call_next):
"""Sets the FastAPI root_path dynamically from the ASGI request data."""
root_path = request.scope["root_path"]
if root_path:
app.root_path = root_path
response = await call_next(request)
return response
Of course this relies upon the proxy setting the root_path in the request correctly. There is an open issue on Mangum that covers this for AWS Lambda - Kludex/mangum#147
My suggestion
- Would simple piece of middleware be the way to go?
- Seems to me the proxy should be responsible for sending the right
root_path and then things can be nice and clean within FastAPI
Thanks
This approach may help remove some of the ongoing confusion and errors people are finding with the root path and proxy settings.
The
ROOT_PATHsolution you implemented works well in FastAPI providing you have the app running on an endpoint that has a fixed root path. I like it.But when deploying FastAPI on AWS Lambda as I have been doing, AWS uses different root paths depending upon your 'stage name'. Hardcoding
ROOT_PATHparameters is not good for portability of course and in fact means I can't run both a/devand a/prodstaging endpoint using the same codebase without having to fiddle with environment variables, which is a bit tricky on AWS Lambda.As per the ASGI spec, the
root_pathshould be passed in the request event body for each lambda call. When thisroot_pathexists and works, this can be dealt with cleanly by a small piece of middleware that reads theroot_pathif it exists and dynamically sets the FastAPI root path.I've tested it and it works, dropping this middleware into the main.py file in FastAPI
Of course this relies upon the proxy setting the
root_pathin the request correctly. There is an open issue on Mangum that covers this for AWS Lambda - Kludex/mangum#147My suggestion
root_pathand then things can be nice and clean within FastAPIThanks