I mounting a flask app on FastAPI with WSGIMiddleware
and I want root "/"
to be my flask app and "/api"
to be a FastAPI route. Here is my code
from fastapi import FastAPI, Request
from fastapi.middleware.wsgi import WSGIMiddleware
from flask import Flask
fastapi = FastAPI()
app = Flask(__name__)
fastapi.mount("/", WSGIMiddleware(app=app))
i run it with uvicorn :
from app import fastapi
import uvicorn
if __name__ == '__main__':
uvicorn.run(fastapi)
this is my route for test for api and flask app :
@fastapi.get("/api")
def test():
return {"hello": "world"}
@app.get("/")
@app.route('/')
def index():
return "Hello world"
Flask part is working perfectly fine, but when I go to http://127.0.0.1:8000/api I get a 404 Not Found
error response. How can I fix this problem?
In your case, you need to make sure to mount
the Flask app at the end of the code, as demonstrated in the example given in the documentation. The reason is simply because the order in which the endpoints are defined matters, as endpoints are evaluated in order (see this answer and this answer for more details and examples).
"Mounting" means adding a complete "independent" application in a specific path, that then takes care of handling all the sub-paths.
This is different from using an
APIRouter
as a mounted application is completely independent. The OpenAPI and docs from your main application won't include anything from the mounted application, etc.
Thus, since you are mounting the Flask app under the path /
, every request under that path will be handled by the Flask application, while the rest will be handled by FastAPI. Hence, the 404 Not Found
error response when trying to hit the /api
endpoint. This response actually comes from the Flask app, since it does not include a /api
endpoint. So, you need to define the /api
endpoint from FastAPI app before mounting the Flask app, as shown in the example given below. If you mounted the Flask app under a different path, such as /v1
, that would not interfere with any of FastAPI's endpoints, you could still mount the Flask app in the way you currently do.
from fastapi import FastAPI
from fastapi.middleware.wsgi import WSGIMiddleware
from flask import Flask, escape, request
flask_app = Flask(__name__)
@flask_app.route("/")
def flask_main():
name = request.args.get("name", "World")
return f"Hello, {escape(name)} from Flask!"
app = FastAPI()
@app.get("/api")
def read_main():
return {"message": "Hello World"}
app.mount("/", WSGIMiddleware(flask_app))