Ep. 30 Application factory pattern
Application factory pattern | Learning Flask Ep. 30
Building scalable Flask applications from the start using the application factory pattern, blueprints and the current_app proxy
The application factory pattern in combination with Blueprints and the current_app
proxy, provide a scalable, consistent and pluggable structural foundation for many Flask applications.
In this article, I'll give you a quick high level overview and a few examples of using this pattern.
It's common to see many Flask applications start out with the following structure:
In this example, we have a views.py
file containing the application routes, static
and templates
directories for our static assets and HTML templates respectively, along with an __init__.py
file to create the app
object and register our routes.
A minimal app
In it's most simple form, a Flask application can be created with the following few lines of code:
To avoid circular dependency issues, we must import views
after creating the app
variable, along with any other objects we need to import that reference the app
object.
Importing the app
object
app
objectMany other files in the application will need access to the app
object created in the __init__.py
file, such as registering routes, logging or accessing config values.
To do so, we must import it first:
We now have access to the app
object for logging, accessing config values and registering the index
route.
While this solution works, it's not particularly elgant or scalable, especially when it comes to writing tests for the app.
A better solution is to create a function in the __init__.py
file that builds the application object and returns it, often referred to as an application factory.
The application factory
As your Flask application grows, you'll often find the need to register blueprints, dynamically load configuration, add request handlers etc..
The application factory is a function that wraps the creating of the app
object and returns it.
Here's an example, we'll go back and refactor our own __init__.py
file shortly:
Unlike the previous example, we're now unable to directly reference the app
variable throughout the aplication, so what now?
We should take advantage of Flask's Blueprint feature, replacing any @app.route
decorators with the newly created blueprint, along with another Flask feature - current_app
.
Accessing the current_app
current_app
Having wrapped the app
object inside of the create_app
function, we still need a way to access it other than calling the function itself.
Flask provides an import called current_app
, which acts as a proxy to the current application and can be used as if you were calling app
itself - Neat!
Let's recreate the views.py
file above using a Blueprint and referencing the current_app
proxy:
As you can see, we didn't have to change much. We can even reference the app
object by renaming the import.
Before we can access the route, we need to register the new Blueprint with the application. We'll do this in the create_app
function.
Registering the Blueprint in the application factory
I'll now refactor the __init__.py
file to include the create_app
function and register the Blueprint:
Running the app gives us the same output as before, however in a much more modular, scalable and testable way.
The create_app
function can now easily be imported to your Python tests, called and take arguments, providing a dynamic way to load different configurations or trigger different behaviour etc..
Wrapping up
Application factories such as the create_app
function shown in this article, combined with the excellent Blueprint feature are the building blocks of robust and scalable Flask applications.
Last update : 30 Dec 2019 Reference : https://pythonise.com/series/learning-flask/application-factory-pattern-%7C-learning-flask-ep.-30
Last updated