Is it possible to use different middleware for different routes/path?
In my case my need comes from CORS. But, I am sure there is other cases than CORS requirements that someone would need different middlewares for different paths.
myapi.com/path1 to allow origins of calls from myfrontend.commyapi.com/path2 to allow origins of calls from anywhere ('*') since it is a public facing api.I checked if it was possible to add a middleware at a router level and did not find any documentation about it.
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
app = FastAPI()
app.add_middleware(
CORSMiddleware,
allow_origins=['myfrontend.com'],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
# I want /path1 to allow only calls from 'myfrontend.com'
@app.get("/path1")
async def path1():
return {"status": "alive"}
# I want /path2 to be a public facing api that can be accessed from anywhere ['*']
@app.get("/path2")
async def path2():
return {"status": "alive"}
I haven't use this way, but you can have a try.
How about use subapp?
documention
Thank you @Dustyposa this looks exactly like what I was looking for.
Here is a example implementation in case someone else stumble upon the same problem
# app1.py
from fastapi import FastAPI
app1 = FastAPI(openapi_prefix="/app1")
@app1.get("path1")
async def path1():
return { "message": "app1"}
# app2.py
from fastapi import FastAPI
app2 = FastAPI(openapi_prefix="/app2")
@app1.get("path2")
async def path2():
return { "message": "app2"}
# main.py
from fastapi import FastAPI
from app1 import app1
from app2 import app2
app1.add_middleware(
CORSMiddleware,
allow_origins=['myfrontend.com'],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
# here we can add middlewares that are only for app2 and not executed on paths of app1
# the CORS policy is different for app2. (allows '*' instead of 'myfrontend.com')
app2.add_middleware(
CORSMiddleware,
allow_origins=['*'],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
app = FastAPI()
app.mount(app1, "/app1")
app.mount(app2, "/app2")
@app.get("/")
async def root():
return {"message": "alive"}
Thanks for your help here @Dustyposa :bowing_man: :cake:
And thanks for reporting back and closing the issue @philippegirard :rocket:
Most helpful comment
Thank you @Dustyposa this looks exactly like what I was looking for.
Here is a example implementation in case someone else stumble upon the same problem