Using Blueprint to Organize Flask Apps
Sachin
Posted on November 26, 2023
Introduction
Large applications can become complex and difficult to manage due to the presence of numerous components and intricate structures.
Flask blueprints help in organizing large applications into smaller, manageable components, leading to enhanced maintainability of the application.
Blueprints can contain views, templates, and static files for various components, similar to the structure of a typical Flask application. These blueprints can be registered with the Flask app to integrate them into the application.
Flask App Structure
If you've used the Flask framework before, you might structure your Flask application as follows:
.
├── app.py
├── static/
└── templates/
└── index.html
After you've created the structure for your app, you'll add some code to the app.py
file.
# app.py
from flask import Flask, render_template
app = Flask(__name__)
@app.route("/")
def home():
return render_template("index.html")
In smaller projects, defining views within the main file may not pose a significant problem. However, in more complex projects, when you need to create routes for various components such as user management, admin functions, profiles, voting, and more, organizing these routes within a single file can become challenging. This can lead to poor code maintainability and make the project harder to manage.
This is precisely where blueprints prove valuable, as they allow you to structure your application into smaller components, enhancing maintainability.
Creating the Blueprint
Add the following code to a new Python file at the root level, blueprint.py
.
# blueprint.py
from flask import Blueprint
bp = Blueprint("blueprint", __name__)
@bp.route("/")
def home():
return "<h1>Hello</h1>"
@bp.route("/user")
def user_info():
return "<h1>User Info</h1>"
The code imports the Blueprint
class from the flask
which will help in defining the routes.
The instance of the Blueprint
is created by calling Blueprint("blueprint", __name__)
and passed in two arguments, first, "blueprint"
, is the Blueprint's name, and the second, __name__
, is the Blueprint's import name. After that, the instance is saved in the bp
variable.
The routes are defined using the Blueprint instance (bp
) in a similar manner to how routes are defined using the Flask application instance (app
).
The @bp.route()
decorators are used to associate URL routes with the view functions defined within the blueprint. The home()
function is associated with the root URL ("/"
), and the user_info()
function is associated with the "/user"
URL.
Registering the Blueprint
A blueprint is similar to a Flask app, but it is not an app, instead, the blueprint must be registered within the Flask app to extend its functionality.
Navigate to the main Flask app created in the app.py
Python file and register the above-created blueprint.
# app.py
from flask import Flask
from blueprint import bp
# Flask app instance
app = Flask(__name__)
app.register_blueprint(bp)
if __name__ == "__main__":
app.run(debug=True)
The code imports the Blueprint instance, bp
, from the blueprint
module (blueprint.py
), and this import includes all of the blueprint's routes and views.
The register_blueprint()
method is then used to register the blueprint instance (bp
) with the Flask app instance (app
).
If you run the app, you can access the routes defined within the blueprint.
Mounting Blueprints at Different Locations
Blueprints can be attached to a certain URL path that can be prefixed with all of the routes defined within the blueprint.
You can make this happen by using the url_prefix
parameter while registering the blueprint using the register_blueprint()
method in the Flask app.
# app.py
from flask import Flask
from blueprint import bp
# Flask app instance
app = Flask(__name__)
app.register_blueprint(bp, url_prefix="/demo")
if __name__ == "__main__":
app.run(debug=True)
The url_prefix
is now "/demo"
. This means that the routes within the blueprint ("/"
and "/user"
) can be accessed by adding "/demo"
at the beginning of their URL paths.
The complete URL of the ("/"
) route is changed to "/demo/"
for the home()
function. Also, the complete URL of the "/user"
route will now be "/demo/user"
for the user_info()
function.
You can set the url_prefix
while making the Blueprint instance. The Blueprint class offers a url_prefix
parameter, and the provided code example demonstrates its usage.
# blueprint.py
from flask import Blueprint
bp = Blueprint("blueprint", __name__, url_prefix="/sample")
The URL path for the ("/"
) route will become "/sample/"
. Likewise, the URL path for the "/user"
route will change to "/sample/user"
.
Note: If you set the url_prefix
parameter inside the blueprint, avoid setting it again during the blueprint registration. Doing so will overwrite the blueprint's URL prefix.
Caution:
If you set url_prefix in the blueprint and then set it again while registering the blueprint within the app, the latter will overwrite the former.
Templates and Static Folders
You have several options for organizing your app using blueprints.
.
└── app/
├── __init__.py
├── admin/
│ ├── __init__.py
│ ├── routes.py
│ ├── static/
│ └── templates/
├── user/
│ ├── __init__.py
│ ├── routes.py
│ ├── static/
│ └── templates/
└── models.py
If your project's structure aligns with the example above, you'll have to indicate the locations of templates and static folders within your Blueprint
.
The Blueprint
class gives you parameters, templates_folder
and static_folder
, which allow you to define the exact path (either absolute or relative) to the blueprint's templates and static folder when creating an instance of the Blueprint
class.
# admin/routes.py
from flask import Blueprint
admin_bp = Blueprint("admin_blueprint",
__name__,
template_folder="templates",
static_folder="static")
# user/routes.py
from flask import Blueprint
user_bp = Blueprint("user_blueprint",
__name__,
template_folder="templates",
static_folder="static")
Both "admin_bp"
and "user_bp"
blueprints have their own directories for templates and static files. This separation ensures that their respective templates and assets are kept separate from other parts of the app, maintaining isolation and organization.
Avoid Template Name Clashes
When you're designing blueprints for different parts of your application, the arrangement of your project holds significance. For instance, referring to the layout mentioned above, duplicating HTML filenames in the admin/templates and user/templates directories can lead to naming clashes.
The Flask application searches for templates in the "templates"
directory. If there are duplicate template file paths across different blueprints, the one that takes precedence depends on the order of blueprint registration. The one registered later will override the earlier one.
To avoid potential issues, you can shape the project layout in the following manner:
.
└── app/
├── app.py
├── models.py
├── admin/
│ ├── __init__.py
│ ├── routes.py
│ ├── static/
│ └── templates/
│ └── admin/
│ └── index.html
└── user/
├── __init__.py
├── routes.py
├── static/
└── templates/
└── user/
└── index.html
Alternatively, you can assign distinct names to the templates.
Template Routing with Blueprints
Template routing with blueprints is distinct from the conventional approach. It involves a specific format where the blueprint name is added as a prefix to the associated view function.
As an example, if your blueprint is named admin_blueprint
and includes a view function named home()
, then the format becomes admin_blueprint.home
.
admin/templates/admin/index.html
<a href="{{ url_for('user_blueprint.home') }}">User</a>
The link mentioned above points to the route connected with the home()
function in the user_blueprint
. The url_for()
function dynamically produces a URL for the user_blueprint.home
route.
user/templates/user/index.html
<a href="{{ url_for('admin_blueprint.home') }}">Admin</a>
Likewise, the situation is identical to the link mentioned earlier. It leads to the route linked with the home
function in the admin_blueprint
. The url_for()
function dynamically generates a URL for the admin_blueprint.home
route.
Including CSS Files with Blueprints: Creating URLs for Static Assets
The procedure is quite similar to what you did with templates. To include or provide CSS files within the HTML template, you should construct a URL that directs to the CSS file situated in the specified static folder of the blueprint.
As an example, the method to link the "style.css"
file found in the static
directory of the "admin_blueprint"
blueprint would be url_for('admin_blueprint.static', filename='style.css')
.
Note: You must indicate the directory path where static files (CSS, JavaScript, images, etc.) are situated for this blueprint. This is achieved using the static_folder
parameter.
admin/templates/admin/index.html
<link rel="stylesheet" href="{{ url_for('admin_blueprint.static', filename='style.css') }}">
This HTML code snippet above uses the url_for()
function to generate a URL that points to the "style.css" static file linked to the admin_blueprint
.
Custom URL Path for Static Files
Flask Blueprint provides a static_url_path
parameter that provides flexibility to define a custom URL prefix for the static files (CSS, JavaScript, images, etc.) associated with the Blueprint
.
# admin/routes.py
from flask import Blueprint
admin_bp = Blueprint("admin_blueprint",
__name__,
template_folder="templates",
static_folder='static',
static_url_path='admin')
The static_url_path
is established as "admin"
, effectively making the static files within the admin_blueprint
accessible under the admin/
URL path.
Now you can directly include static files (CSS, JavaScript, images, etc) by specifying the static URL path.
Including Static Files using Static URL Path
<link rel="stylesheet" href="admin/style.css">
<!--Body Section-->
<img src="admin/partners.png">
The complete webpage would look like the image shown below:
Conclusion
A Flask Blueprint is used as an extension for a Flask app, and it serves the purpose of organizing large and complex applications into smaller, more manageable components.
Let's recall what you've seen in this tutorial:
What is Blueprint in Flask
Creating and Registering a Blueprint
Template routing with Blueprint
Including static files with Blueprint
Custom URL path for static assets
🏆Other articles you might be interested in if you liked this one
✅Upload and display images on the frontend using Flask in Python.
✅Building a Flask image recognition webapp using a deep learning model.
✅How to connect the SQLite database with Flask app using Python?
✅How to create a database in Appwrite using Python?
✅How to Integrate TailwindCSS with Flask?
✅What is context manager and how to use them using with statement?
That's all for now
Keep Coding✌✌
Posted on November 26, 2023
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.