Skip to content

Instantly share code, notes, and snippets.

@BlackHacked
Forked from gdamjan/README.md
Created March 24, 2025 08:55
Show Gist options
  • Save BlackHacked/ddccf16370204cc97b3ca01c76d53a6d to your computer and use it in GitHub Desktop.
Save BlackHacked/ddccf16370204cc97b3ca01c76d53a6d to your computer and use it in GitHub Desktop.
fastapi and proxies

Quickstart

pdm install

These are equivalent (given the main.py code)

UVICORN_ROOT_PATH=/api/ pdm run uvicorn main:app
FASTAPI_ROOT_PATH=/api/ pdm run uvicorn main:app
pdm run uvicorn main:app --root-path /api

Expected response from all 3 variants:

$ curl http://127.0.0.1:8000/
{"message":"Hello World","root_path":"/api/"}

But

AWS ALB doesn't do url path rewriting, so when we have a Listener Rule that forward all requests that match an /api prefix to our FastAPI backend, it will pass back the whole url, including the prefix. So what we really need to work is this:

$ curl http://127.0.0.1:8000/api/
{"message":"Hello World","root_path":"/api/"}

without changing the whole application.

References

from fastapi import FastAPI, Request
from proxy_middleware import ProxyPrefixMiddleware
import os
root_path = os.environ.get("FASTAPI_ROOT_PATH")
app = FastAPI(root_path=root_path)
if root_path:
app.add_middleware(ProxyPrefixMiddleware)
@app.get("/")
async def root(request: Request):
return {"message": "Hello World", "root_path": request.scope.get("root_path")}
'''
Usage:
if root_path:
app.add_middleware(ProxyPrefixMiddleware)
'''
class ProxyPrefixMiddleware:
def __init__(self, app):
self.app = app
async def __call__(self, scope, receive, send):
if scope["type"] in {"http", "websocket"}:
root_path = scope["root_path"].rstrip('/')
scope["path"] = scope["path"].removeprefix(root_path)
await self.app(scope, receive, send)
[project]
name = "fastapi-proxies"
version = "0.0.1"
description = ""
authors = []
dependencies = [
"fastapi>=0.99.1",
"uvicorn>=0.22.0",
]
requires-python = ">=3.9"
license = {text = "MIT"}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment