@@ -15,41 +15,38 @@ applications.
15
15
Basic Usage
16
16
-----------
17
17
18
- After installation of Flask you will now find a :command: `flask ` script installed
19
- into your virtualenv. If you don't want to install Flask or you have a
20
- special use-case you can also use ``python -m flask `` to accomplish exactly
21
- the same.
18
+ After installation of Flask you will now find a :command: `flask ` script
19
+ installed into your virtualenv. If you don't want to install Flask or you
20
+ have a special use-case you can also use ``python -m flask `` to accomplish
21
+ exactly the same.
22
22
23
23
The way this script works is by providing access to all the commands on
24
24
your Flask application's :attr: `Flask.cli ` instance as well as some
25
25
built-in commands that are always there. Flask extensions can also
26
26
register more commands there if they desire so.
27
27
28
- For the :command: `flask ` script to work, an application needs to be discovered.
29
- The two most common ways are either an environment variable
30
- (``FLASK_APP ``) or the :option: `--app ` / :option: `-a ` parameter. It should be the
31
- import path for your application or the path to a Python file. In the
32
- latter case Flask will attempt to setup the Python path for you
33
- automatically and discover the module name but that might not always work.
28
+ For the :command: `flask ` script to work, an application needs to be
29
+ discovered. This is achieved by exporting the ``FLASK_APP `` environment
30
+ variable. It can be either set to an import path or to a filename of a
31
+ Python module that contains a Flask application.
34
32
35
33
In that imported file the name of the app needs to be called ``app `` or
36
- optionally be specified after a colon.
34
+ optionally be specified after a colon. For instance
35
+ `mymodule:application ` would tell it to use the `application ` object in
36
+ the :file: `mymodule.py ` file.
37
37
38
- Given a :file: `hello.py ` file with the application in it named ``app `` this is
39
- how it can be run.
38
+ Given a :file: `hello.py ` file with the application in it named ``app ``
39
+ this is how it can be run.
40
40
41
41
Environment variables (On Windows use ``set `` instead of ``export ``)::
42
42
43
43
export FLASK_APP=hello
44
44
flask run
45
45
46
- Parameters ::
46
+ Or with a filename ::
47
47
48
- flask --app=hello run
49
-
50
- File names::
51
-
52
- flask --app=hello.py run
48
+ export FLASK_APP=/path/to/hello.py
49
+ flask run
53
50
54
51
Virtualenv Integration
55
52
----------------------
@@ -62,16 +59,20 @@ automatically also activate the correct application name.
62
59
Debug Flag
63
60
----------
64
61
65
- The :command: `flask ` script can be run with :option: `--debug ` or :option: `--no-debug ` to
66
- automatically flip the debug flag of the application. This can also be
67
- configured by setting ``FLASK_DEBUG `` to ``1 `` or ``0 ``.
62
+ The :command: `flask ` script can also be instructed to enable the debug
63
+ mode of the application automatically by exporting ``FLASK_DEBUG ``. If
64
+ set to ``1 `` debug is enabled or ``0 `` disables it.
65
+
66
+ Or with a filename::
67
+
68
+ export FLASK_DEBUG=1
68
69
69
70
Running a Shell
70
71
---------------
71
72
72
73
To run an interactive Python shell you can use the ``shell `` command::
73
74
74
- flask --app=hello shell
75
+ flask shell
75
76
76
77
This will start up an interactive Python shell, setup the correct
77
78
application context and setup the local variables in the shell. This is
@@ -86,18 +87,19 @@ easily. Flask uses `click`_ for the command interface which makes
86
87
creating custom commands very easy. For instance if you want a shell
87
88
command to initialize the database you can do this::
88
89
90
+ import click
89
91
from flask import Flask
90
92
91
93
app = Flask(__name__)
92
94
93
95
@app.cli.command()
94
96
def initdb():
95
97
"""Initialize the database."""
96
- print 'Init the db'
98
+ click.echo( 'Init the db')
97
99
98
100
The command will then show up on the command line::
99
101
100
- $ flask -a hello.py initdb
102
+ $ flask initdb
101
103
Init the db
102
104
103
105
Application Context
@@ -122,12 +124,12 @@ Factory Functions
122
124
-----------------
123
125
124
126
In case you are using factory functions to create your application (see
125
- :ref: `app-factories `) you will discover that the :command: `flask ` command cannot
126
- work with them directly. Flask won't be able to figure out how to
127
+ :ref: `app-factories `) you will discover that the :command: `flask ` command
128
+ cannot work with them directly. Flask won't be able to figure out how to
127
129
instantiate your application properly by itself. Because of this reason
128
130
the recommendation is to create a separate file that instantiates
129
- applications. This is by far not the only way to make this work. Another
130
- is the :ref: `custom-scripts ` support.
131
+ applications. This is not the only way to make this work. Another is the
132
+ :ref: `custom-scripts ` support.
131
133
132
134
For instance if you have a factory function that creates an application
133
135
from a filename you could make a separate file that creates such an
@@ -152,48 +154,42 @@ From this point onwards :command:`flask` will find your application.
152
154
Custom Scripts
153
155
--------------
154
156
155
- While the most common way is to use the :command: `flask ` command, you can also
156
- make your own "driver scripts". Since Flask uses click for the scripts
157
- there is no reason you cannot hook these scripts into any click
157
+ While the most common way is to use the :command: `flask ` command, you can
158
+ also make your own "driver scripts". Since Flask uses click for the
159
+ scripts there is no reason you cannot hook these scripts into any click
158
160
application. There is one big caveat and that is, that commands
159
161
registered to :attr: `Flask.cli ` will expect to be (indirectly at least)
160
162
launched from a :class: `flask.cli.FlaskGroup ` click group. This is
161
163
necessary so that the commands know which Flask application they have to
162
164
work with.
163
165
164
166
To understand why you might want custom scripts you need to understand how
165
- click finds and executes the Flask application. If you use the :command: ` flask `
166
- script you specify the application to work with on the command line or
167
- environment variable as an import name. This is simple but it has some
168
- limitations. Primarily it does not work with application factory
169
- functions (see :ref: `app-factories `).
167
+ click finds and executes the Flask application. If you use the
168
+ :command: ` flask ` script you specify the application to work with on the
169
+ command line or environment variable as an import name. This is simple
170
+ but it has some limitations. Primarily it does not work with application
171
+ factory functions (see :ref: `app-factories `).
170
172
171
173
With a custom script you don't have this problem as you can fully
172
174
customize how the application will be created. This is very useful if you
173
175
write reusable applications that you want to ship to users and they should
174
176
be presented with a custom management script.
175
177
176
- If you are used to writing click applications this will look familiar but
177
- at the same time, slightly different because of how commands are loaded.
178
- We won't go into detail now about the differences but if you are curious
179
- you can have a look at the :ref: `script-info-object ` section to learn all
180
- about it.
181
-
182
178
To explain all of this, here is an example :file: `manage.py ` script that
183
179
manages a hypothetical wiki application. We will go through the details
184
180
afterwards::
185
181
182
+ import os
186
183
import click
187
- from flask.cli import FlaskGroup, script_info_option
184
+ from flask.cli import FlaskGroup
188
185
189
186
def create_wiki_app(info):
190
187
from yourwiki import create_app
191
- config = info.data.get('config') or 'wikiconfig.py'
192
- return create_app( config=config )
188
+ return create_app(
189
+ config=os.environ.get('WIKI_CONFIG', 'wikiconfig.py') )
193
190
194
191
@click.group(cls=FlaskGroup, create_app=create_wiki_app)
195
- @script_info_option('--config', script_info_key='config')
196
- def cli(**params):
192
+ def cli():
197
193
"""This is a management script for the wiki application."""
198
194
199
195
if __name__ == '__main__':
@@ -204,56 +200,17 @@ step.
204
200
205
201
1. First we import the ``click `` library as well as the click extensions
206
202
from the ``flask.cli `` package. Primarily we are here interested
207
- in the :class: `~flask.cli.FlaskGroup ` click group and the
208
- :func: `~flask.cli.script_info_option ` decorator.
203
+ in the :class: `~flask.cli.FlaskGroup ` click group.
209
204
2. The next thing we do is defining a function that is invoked with the
210
- script info object (:ref: ` script-info-object `) from Flask and its
205
+ script info object (:class: ` ~flask.cli.ScriptInfo `) from Flask and its
211
206
purpose is to fully import and create the application. This can
212
207
either directly import an application object or create it (see
213
- :ref: `app-factories `).
214
-
215
- What is ``info.data ``? It's a dictionary of arbitrary data on the
216
- script info that can be filled by options or through other means. We
217
- will come back to this later.
208
+ :ref: `app-factories `). In this case we load the config from an
209
+ environment variable.
218
210
3. Next step is to create a :class: `FlaskGroup `. In this case we just
219
211
make an empty function with a help doc string that just does nothing
220
212
and then pass the ``create_wiki_app `` function as a factory function.
221
213
222
214
Whenever click now needs to operate on a Flask application it will
223
215
call that function with the script info and ask for it to be created.
224
- 4. In step 2 you could see that the config is passed to the actual
225
- creation function. This config comes from the :func: `script_info_option `
226
- decorator for the main script. It accepts a :option: `--config ` option and
227
- then stores it in the script info so we can use it to create the
228
- application.
229
- 5. All is rounded up by invoking the script.
230
-
231
- .. _script-info-object :
232
-
233
- The Script Info
234
- ---------------
235
-
236
- The Flask script integration might be confusing at first, but there is a reason
237
- why it's done this way. The reason for this is that Flask wants to
238
- both provide custom commands to click as well as not loading your
239
- application unless it has to. The reason for this is added flexibility.
240
-
241
- This way an application can provide custom commands, but even in the
242
- absence of an application the :command: `flask ` script is still operational on a
243
- basic level. In addition to that it means that the individual commands
244
- have the option to avoid creating an instance of the Flask application
245
- unless required. This is very useful as it allows the server commands for
246
- instance to load the application on a first request instead of
247
- immediately, therefore giving a better debug experience.
248
-
249
- All of this is provided through the :class: `flask.cli.ScriptInfo ` object
250
- and some helper utilities around. The basic way it operates is that when
251
- the :class: `flask.cli.FlaskGroup ` executes as a script it creates a script
252
- info and keeps it around. From that point onwards modifications on the
253
- script info can be done through click options. To simplify this pattern
254
- the :func: `flask.cli.script_info_option ` decorator was added.
255
-
256
- Once Flask actually needs the individual Flask application it will invoke
257
- the :meth: `flask.cli.ScriptInfo.load_app ` method. This happens when the
258
- server starts, when the shell is launched or when the script looks for an
259
- application-provided click command.
216
+ 4. All is rounded up by invoking the script.
0 commit comments