1Application Factories
2=====================
3
4If you are already using packages and blueprints for your application
5(:doc:`/blueprints`) there are a couple of really nice ways to further improve
6the experience.  A common pattern is creating the application object when
7the blueprint is imported.  But if you move the creation of this object
8into a function, you can then create multiple instances of this app later.
9
10So why would you want to do this?
11
121.  Testing.  You can have instances of the application with different
13    settings to test every case.
142.  Multiple instances.  Imagine you want to run different versions of the
15    same application.  Of course you could have multiple instances with
16    different configs set up in your webserver, but if you use factories,
17    you can have multiple instances of the same application running in the
18    same application process which can be handy.
19
20So how would you then actually implement that?
21
22Basic Factories
23---------------
24
25The idea is to set up the application in a function.  Like this::
26
27    def create_app(config_filename):
28        app = Flask(__name__)
29        app.config.from_pyfile(config_filename)
30
31        from yourapplication.model import db
32        db.init_app(app)
33
34        from yourapplication.views.admin import admin
35        from yourapplication.views.frontend import frontend
36        app.register_blueprint(admin)
37        app.register_blueprint(frontend)
38
39        return app
40
41The downside is that you cannot use the application object in the blueprints
42at import time.  You can however use it from within a request.  How do you
43get access to the application with the config?  Use
44:data:`~flask.current_app`::
45
46    from flask import current_app, Blueprint, render_template
47    admin = Blueprint('admin', __name__, url_prefix='/admin')
48
49    @admin.route('/')
50    def index():
51        return render_template(current_app.config['INDEX_TEMPLATE'])
52
53Here we look up the name of a template in the config.
54
55Factories & Extensions
56----------------------
57
58It's preferable to create your extensions and app factories so that the
59extension object does not initially get bound to the application.
60
61Using `Flask-SQLAlchemy <https://flask-sqlalchemy.palletsprojects.com/>`_,
62as an example, you should not do something along those lines::
63
64    def create_app(config_filename):
65        app = Flask(__name__)
66        app.config.from_pyfile(config_filename)
67
68        db = SQLAlchemy(app)
69
70But, rather, in model.py (or equivalent)::
71
72    db = SQLAlchemy()
73
74and in your application.py (or equivalent)::
75
76    def create_app(config_filename):
77        app = Flask(__name__)
78        app.config.from_pyfile(config_filename)
79
80        from yourapplication.model import db
81        db.init_app(app)
82
83Using this design pattern, no application-specific state is stored on the
84extension object, so one extension object can be used for multiple apps.
85For more information about the design of extensions refer to :doc:`/extensiondev`.
86
87Using Applications
88------------------
89
90To run such an application, you can use the :command:`flask` command:
91
92.. tabs::
93
94   .. group-tab:: Bash
95
96      .. code-block:: text
97
98         $ export FLASK_APP=myapp
99         $ flask run
100
101   .. group-tab:: CMD
102
103      .. code-block:: text
104
105         > set FLASK_APP=myapp
106         > flask run
107
108   .. group-tab:: Powershell
109
110      .. code-block:: text
111
112         > $env:FLASK_APP = "myapp"
113         > flask run
114
115Flask will automatically detect the factory (``create_app`` or ``make_app``)
116in ``myapp``. You can also pass arguments to the factory like this:
117
118.. tabs::
119
120   .. group-tab:: Bash
121
122      .. code-block:: text
123
124         $ export FLASK_APP="myapp:create_app('dev')"
125         $ flask run
126
127   .. group-tab:: CMD
128
129      .. code-block:: text
130
131         > set FLASK_APP="myapp:create_app('dev')"
132         > flask run
133
134   .. group-tab:: Powershell
135
136      .. code-block:: text
137
138         > $env:FLASK_APP = "myapp:create_app('dev')"
139         > flask run
140
141Then the ``create_app`` factory in ``myapp`` is called with the string
142``'dev'`` as the argument. See :doc:`/cli` for more detail.
143
144Factory Improvements
145--------------------
146
147The factory function above is not very clever, but you can improve it.
148The following changes are straightforward to implement:
149
1501.  Make it possible to pass in configuration values for unit tests so that
151    you don't have to create config files on the filesystem.
1522.  Call a function from a blueprint when the application is setting up so
153    that you have a place to modify attributes of the application (like
154    hooking in before/after request handlers etc.)
1553.  Add in WSGI middlewares when the application is being created if necessary.
156