If you are already using packages and blueprints for your application (Modular Applications with Blueprints) there are a couple of really nice ways to further improve the experience. A common pattern is creating the application object when the blueprint is imported. But if you move the creation of this object into a function, you can then create multiple instances of this app later.
So why would you want to do this?
So how would you then actually implement that?
The idea is to set up the application in a function. Like this:
def create_app(config_filename): app = Flask(__name__) app.config.from_pyfile(config_filename) from yourapplication.model import db db.init_app(app) from yourapplication.views.admin import admin from yourapplication.views.frontend import frontend app.register_blueprint(admin) app.register_blueprint(frontend) return app
The downside is that you cannot use the application object in the blueprints at import time. You can however use it from within a request. How do you get access to the application with the config? Use current_app
:
from flask import current_app, Blueprint, render_template admin = Blueprint('admin', __name__, url_prefix='/admin') @admin.route('/') def index(): return render_template(current_app.config['INDEX_TEMPLATE'])
Here we look up the name of a template in the config.
It’s preferable to create your extensions and app factories so that the extension object does not initially get bound to the application.
Using Flask-SQLAlchemy, as an example, you should not do something along those lines:
def create_app(config_filename): app = Flask(__name__) app.config.from_pyfile(config_filename) db = SQLAlchemy(app)
But, rather, in model.py (or equivalent):
db = SQLAlchemy()
and in your application.py (or equivalent):
def create_app(config_filename): app = Flask(__name__) app.config.from_pyfile(config_filename) from yourapplication.model import db db.init_app(app)
Using this design pattern, no application-specific state is stored on the extension object, so one extension object can be used for multiple apps. For more information about the design of extensions refer to Flask Extension Development.
To run such an application, you can use the flask command:
$ export FLASK_APP=myapp $ flask run
Flask will automatically detect the factory (create_app
or make_app
) in myapp
. You can also pass arguments to the factory like this:
$ export FLASK_APP="myapp:create_app('dev')" $ flask run
Then the create_app
factory in myapp
is called with the string 'dev'
as the argument. See Command Line Interface for more detail.
The factory function above is not very clever, but you can improve it. The following changes are straightforward to implement:
© 2007–2020 Pallets
Licensed under the BSD 3-clause License.
https://flask.palletsprojects.com/en/1.1.x/patterns/appfactories/