Skillversitas

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.