Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Root_path - setting dynamically from ASGI request using FastAPI middleware #2929

@ttamg

Description

@ttamg

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

  1. Would simple piece of middleware be the way to go?
  2. 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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions