Copied to Clipboard
You can also use the template filter decorator.
Since in FastAPI you had to instantiate the templates variable, you’ll also use that variable to pass along the new filter. The templates variable has the env property allowing you to access the filters dictionary as you can see below:
templates.env.filters['to_pretty_json'] = to_pretty_json
Static files folder
Much like templates, both Flask and FastAPI, allow you to bundle the static files (CSS, JavaScript, and images) under the same folder, but once again there are a few differences.
Flask supports static files out of the gate with no configuration needed, you only need to add the static/ folder to your project, and that’s it, you don’t need any extra configuration to access static files from your templates.
For FastAPI, much like the template folder, you need to set the location of the static file by using the mount property, which is also known as "mounting" the static files, and the StaticFiles class to instantiate the directory.
from fastapi.staticfiles import StaticFiles
app = FastAPI()
app.mount(
"/static",
StaticFiles(directory="static"),
name="static"
)
Note that this way of creating the static files folder within the app creates an independent application and won’t be picked up by the OpenAPI or the docs but you’ll still be able to use things like the url_for function on your templates.
Using url_for function on the templates
Both templates on Flask and FastAPI will allow you to programmatically define URLs for files and endpoints using the url_for function, but as you can expect the parameters differ on each framework.
For example, in Flask, to add the style sheet on your base.html, you pass along the folder name static followed by the parameter named filename containing the name of your CSS file.
<link href="{{ url_for('static', filename='style.css') }}" rel="stylesheet" />
For FastAPI the functionality of the url_for function will be the same, but the parameter for the filename is called path:
<link href="{{ url_for('static', path='style.css') }}" rel="stylesheet" />
Sessions
For web applications, you usually have a way to manage sessions. Below you can see how you can interact with a session in each framework. The example will show how to clear a session when logging out.
In Flask, you can access the session from the session object that can be imported from the flask module as you can see below:
from flask import session
# ... blueprint definition
@auth_bp.route("/logout")
def logout():
"""
Logs the user out of the session
"""
session.clear()
# ... rest of your logout code
Meanwhile, in FastAPI the session is part of the Request object, you can access it by passing the request as part of the endpoint function, and then using it request.session, like so:
from fastapi import Request
# ... router definition
@auth_router.get("/logout")
def logout(request: Request):
"""
Logs the user out of the session
"""
request.session.clear()
# ... rest of your logout code
Modular applications: Blueprint and APIRouter
For more complex applications, which usually include multiple modules inside of an app, you’ll need to use a router so you can have some separation between responsibilities. For this, you will have a Blueprint in Flask and an APIRouter in FastAPI.
After creating the Blueprint or APIRouter you’ll need to register them with your app. Here’s what that looks like for both frameworks.
The Blueprint will need some more configuration like the name of that blueprint (’webapp’) as well as the import name (__name__) and any other configuration necessary, in this example, we passed along the template folder for the webapp:
from flask import Flask, Blueprint
webapp_bp = Blueprint(
'webapp', __name__ , template_folder="templates"
)
app = Flask( __name__ )
Once the blueprint is created you can register it to your app. This helps make available any views/routes within your blueprint for your application. The registration occurs by calling the register_blueprint method from your app, and passing along the blueprint like so:
from flask import Flask
app = Flask( __name__ )
app.register_blueprint(webapp_bp, url_prefix='/')
For FastAPI the APIRouter will function similarly to the Blueprint in Flask, the difference is that you don’t need to pass any names, take a look:
from fastapi import APIRouter
webapp_router = APIRouter()
Then to register the router you can use the method include_router from your FastAPI app, and pass along the webapp_router like this:
from fastapi import FastAPI
app = FastAPI()
app.include_router(webapp_router)
Using url_for in the endpoints
Other than in templates, you can use the url_for in an endpoint to programmatically define the path for a given endpoint/route.
For using url_for in Flask you gotta import the function from the flask library and then pass the name of the endpoint. If your endpoint is in another module, remember to pass along the name of that module as well like so:
from flask import redirect, url_for
# ... blueprint definition
@auth_bp.route("/logout")
def logout():
# ... your code
return redirect(url_for("webapp.home")
Meanwhile, in FastAPI the url_for is a method and comes from the Request class. You need to pass along the endpoint name, if that endpoint is part of your app, even if it is in another module, everything will work from there and there’s no need to pass the module name as well.
from fastapi import Request
from fastapi import RedirectResponse
# ... router definition
@auth_router.get("/logout")
def logout(request: Request):
# ... your logout code
return RedirectResponse(url=request.url_for("home"))
Recap
Migrating frameworks in an application can be a daunting task especially if you don’t know where things might go wrong after copying and pasting code. But if you know where things will differ the migration will go much more smoothly.
Here’s a short version of the things to keep an eye out for if you are going to migrate from Flask to FastAPI and vice-versa:
- Flask will pick up templates automatically, but FastAPI needs to be told where to find the templates using the
Jinja2Templates class and passing along the templates directory.
- Flask will use the
render_template function to render pages, whereas FastAPI will use TemplateResponse which comes from Jinja2Templates class.
- To create new filters in Flask you use the
jinja_env property, FastAPI will use the env property.
- Flask will pick up the static folder automatically, for FastAPI you need to "mount" the folder and use the
StaticFiles class.
- Sessions are handled differently, for Flask there’s a
session object, for FastAPI the session object is part of the Request class.
- For more complex applications you use
Blueprint in Flask to define new routes whereas in FastAPI you’ll have a similar structure called APIRouter. Remember to register your blueprint or your router with your app.
- Finally, remember to use the
url_for function with the correct parameter filename for Flask and path for FastAPI, and that in your endpoints url_for exists as a standalone function in Flask whereas it is a method from the Request class in FastAPI.
In case you want to see apps in each framework and compare the differences for yourself here are the repositories on GitHub:
Finally, if you went through a similar process what other problems did you face and how did you solve them? I’d love to know more about your experience, send me a message on any of my social profiles.