Mounting a Flask App
Flask is a WSGI framework; FastAPI is ASGI. To run a Flask application inside a FastAPI app you need a bridge that adapts WSGI to ASGI. A small adapter (or the asgiref library) lets you mount a Flask app under a prefix and keep both frameworks in one server.
A Minimal WSGI-to-ASGI Adapter
# wsgi_adapter.py
from asgiref.wsgi import WsgiToAsgi
def wsgi_to_asgi(app):
return WsgiToAsgi(app)
The Flask App
# legacy_app.py
from flask import Flask, jsonify
legacy_app = Flask(__name__)
@legacy_app.route("/legacy/items")
def legacy_items():
return jsonify([{"id": 1, "name": "legacy-1"}, {"id": 2, "name": "legacy-2"}])
Mount in FastAPI
from fastapi import FastAPI
from wsgi_adapter import wsgi_to_asgi
from legacy_app import legacy_app
app = FastAPI()
app.mount("/legacy", wsgi_to_asgi(legacy_app), name="legacy")
@app.get("/")
def root():
return {"fastapi": True, "legacy": "/legacy/legacy/items"}
Requests to /legacy/legacy/items are forwarded to the Flask app with the prefix stripped; everything else stays in FastAPI.
Alternative Approaches
- Reverse proxy: serve Flask on its own port and proxy /legacy from nginx or Caddy to it. Cleanest when the apps must stay independently deployable.
- Werkzeug's WSGI middleware inside a Starlette route: more manual, rarely worth it.
- Gradual porting: wrap legacy Flask endpoints one by one behind FastAPI routes, then retire the adapter.
Gotchas
- The Flask app's URL map should not include the mount prefix; the adapter strips it.
- Debug mode inside the mounted app is rarely what you want; disable Flask's reloader.
- Cookies set by the Flask app apply to the whole host - keep them scoped by path where possible.
Summary
Bridge a WSGI Flask app into FastAPI with asgiref's WsgiToAsgi and app.mount, or keep the Flask app on its own port behind a reverse proxy. Mounting is ideal for gradual migrations where legacy Flask endpoints must keep working while the rest of the system moves to FastAPI.