Skip to content

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

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

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions