Migrating from Flask to FastAPI involves several key changes to your codebase. This guide will walk you through using Codegen to automate this migration, handling imports, route decorators, static files, and template rendering.

You can find the complete example code in our examples repository

Overview

The migration process involves four main steps:

  1. Updating imports and initialization
  2. Converting route decorators
  3. Setting up static file handling
  4. Updating template handling

Let’s walk through each step using Codegen.

I: Update Imports and Initialization

First, we need to update Flask imports to their FastAPI equivalents and modify the app initialization:

Learn more about imports here.

from codegen import Codebase

# Parse the codebase
codebase = Codebase("./")

# Update imports and initialization
for file in codebase.files:
    # Update Flask to FastAPI imports
    for imp in file.imports:
        if imp.name == "Flask":
            imp.set_name("FastAPI")
        elif imp.module == "flask":
            imp.set_module("fastapi")

    # Update app initialization
    for call in file.function_calls:
        if call.name == "Flask":
            call.set_name("FastAPI")
            # Remove __name__ argument (not needed in FastAPI)
            if len(call.args) > 0 and call.args[0].value == "__name__":
                call.args[0].remove()

This transforms code from:

from flask import Flask
app = Flask(__name__)

to:

from fastapi import FastAPI
app = FastAPI()

FastAPI doesn’t require the __name__ argument that Flask uses for template resolution. Codegen automatically removes it during migration.

II: Convert Route Decorators

Next, we update Flask’s route decorators to FastAPI’s operation decorators:

for function in file.functions:
    for decorator in function.decorators:
        if "@app.route" in decorator.source:
            route = decorator.source.split('"')[1]
            method = "get"  # Default to GET
            if "methods=" in decorator.source:
                methods = decorator.source.split("methods=")[1].split("]")[0]
                if "post" in methods.lower():
                    method = "post"
                elif "put" in methods.lower():
                    method = "put"
                elif "delete" in methods.lower():
                    method = "delete"
            decorator.edit(f'@app.{method}("{route}")')

This converts decorators from Flask style:

@app.route("/users", methods=["POST"])
def create_user():
    pass

to FastAPI style:

@app.post("/users")
def create_user():
    pass

FastAPI provides specific decorators for each HTTP method, making the API more explicit and enabling better type checking and OpenAPI documentation.

III: Setup Static Files

FastAPI handles static files differently than Flask. We need to add the StaticFiles mounting:

# Add StaticFiles import
file.add_import_from_import_string("from fastapi.staticfiles import StaticFiles")

# Mount static directory
file.add_symbol_from_source(
    'app.mount("/static", StaticFiles(directory="static"), name="static")'
)

This sets up static file serving equivalent to Flask’s automatic static file handling.

FastAPI requires explicit mounting of static directories, which provides more flexibility in how you serve static files.

IV: Update Template Handling

Finally, we update the template rendering to use FastAPI’s Jinja2Templates:

for func_call in file.function_calls:
    if func_call.name == "render_template":
        # Convert to FastAPI's template response
        func_call.set_name("Jinja2Templates(directory='templates').TemplateResponse")
        if len(func_call.args) > 1:
            # Convert template variables to context dict
            context_arg = ", ".join(
                f"{arg.name}={arg.value}" for arg in func_call.args[1:]
            )
            func_call.set_kwarg("context", f"{'{'}{context_arg}{'}'}")
        # Add required request parameter
        func_call.set_kwarg("request", "request")

This transforms template rendering from Flask style:

@app.get("/users")
def list_users():
    return render_template("users.html", users=users)

to FastAPI style:

@app.get("/users")
def list_users(request: Request):
    return Jinja2Templates(directory="templates").TemplateResponse(
        "users.html",
        context={"users": users},
        request=request
    )

FastAPI requires the request object to be passed to templates. Codegen automatically adds this parameter during migration.

Running the Migration

You can run the complete migration using our example script:

git clone https://github.com/codegen-sh/codegen-examples.git
cd codegen-examples/flask_to_fastapi_migration
python run.py

The script will:

  1. Process all Python files in your codebase
  2. Apply the transformations in the correct order
  3. Maintain your code’s functionality while updating to FastAPI patterns

Next Steps

After migration, you might want to:

  • Add type hints to your route parameters
  • Set up dependency injection
  • Add request/response models
  • Configure CORS and middleware

Check out these related tutorials:

Learn More

Was this page helpful?