Skip to content

Commit a7d829c

Browse files
committedMay 26, 2016
Update docs to the new CLI patterns
1 parent 523e271 commit a7d829c

File tree

10 files changed

+112
-141
lines changed

10 files changed

+112
-141
lines changed
 

‎docs/api.rst

-7
Original file line numberDiff line numberDiff line change
@@ -892,13 +892,6 @@ Command Line Interface
892892
Marks a function so that an instance of :class:`ScriptInfo` is passed
893893
as first argument to the click callback.
894894

895-
.. autofunction:: script_info_option
896-
897-
A special decorator that informs a click callback to be passed the
898-
script info object as first argument. This is normally not useful
899-
unless you implement very special commands like the run command which
900-
does not want the application to be loaded yet.
901-
902895
.. autodata:: run_command
903896

904897
.. autodata:: shell_command

‎docs/cli.rst

+49-92
Original file line numberDiff line numberDiff line change
@@ -15,41 +15,38 @@ applications.
1515
Basic Usage
1616
-----------
1717

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.
2222

2323
The way this script works is by providing access to all the commands on
2424
your Flask application's :attr:`Flask.cli` instance as well as some
2525
built-in commands that are always there. Flask extensions can also
2626
register more commands there if they desire so.
2727

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.
3432

3533
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.
3737

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.
4040

4141
Environment variables (On Windows use ``set`` instead of ``export``)::
4242

4343
export FLASK_APP=hello
4444
flask run
4545

46-
Parameters::
46+
Or with a filename::
4747

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
5350

5451
Virtualenv Integration
5552
----------------------
@@ -62,16 +59,20 @@ automatically also activate the correct application name.
6259
Debug Flag
6360
----------
6461

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
6869

6970
Running a Shell
7071
---------------
7172

7273
To run an interactive Python shell you can use the ``shell`` command::
7374

74-
flask --app=hello shell
75+
flask shell
7576

7677
This will start up an interactive Python shell, setup the correct
7778
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
8687
creating custom commands very easy. For instance if you want a shell
8788
command to initialize the database you can do this::
8889

90+
import click
8991
from flask import Flask
9092

9193
app = Flask(__name__)
9294

9395
@app.cli.command()
9496
def initdb():
9597
"""Initialize the database."""
96-
print 'Init the db'
98+
click.echo('Init the db')
9799

98100
The command will then show up on the command line::
99101

100-
$ flask -a hello.py initdb
102+
$ flask initdb
101103
Init the db
102104

103105
Application Context
@@ -122,12 +124,12 @@ Factory Functions
122124
-----------------
123125

124126
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
127129
instantiate your application properly by itself. Because of this reason
128130
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.
131133

132134
For instance if you have a factory function that creates an application
133135
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.
152154
Custom Scripts
153155
--------------
154156

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
158160
application. There is one big caveat and that is, that commands
159161
registered to :attr:`Flask.cli` will expect to be (indirectly at least)
160162
launched from a :class:`flask.cli.FlaskGroup` click group. This is
161163
necessary so that the commands know which Flask application they have to
162164
work with.
163165

164166
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`).
170172

171173
With a custom script you don't have this problem as you can fully
172174
customize how the application will be created. This is very useful if you
173175
write reusable applications that you want to ship to users and they should
174176
be presented with a custom management script.
175177

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-
182178
To explain all of this, here is an example :file:`manage.py` script that
183179
manages a hypothetical wiki application. We will go through the details
184180
afterwards::
185181

182+
import os
186183
import click
187-
from flask.cli import FlaskGroup, script_info_option
184+
from flask.cli import FlaskGroup
188185

189186
def create_wiki_app(info):
190187
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'))
193190

194191
@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():
197193
"""This is a management script for the wiki application."""
198194

199195
if __name__ == '__main__':
@@ -204,56 +200,17 @@ step.
204200

205201
1. First we import the ``click`` library as well as the click extensions
206202
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.
209204
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
211206
purpose is to fully import and create the application. This can
212207
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.
218210
3. Next step is to create a :class:`FlaskGroup`. In this case we just
219211
make an empty function with a help doc string that just does nothing
220212
and then pass the ``create_wiki_app`` function as a factory function.
221213

222214
Whenever click now needs to operate on a Flask application it will
223215
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.

‎docs/patterns/appfactories.rst

+2-1
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,8 @@ an application::
9999

100100
It can then be used with the :command:`flask` command::
101101

102-
flask --app=exampleapp run
102+
export FLASK_APP=exampleapp
103+
flask run
103104

104105
Factory Improvements
105106
--------------------

‎docs/quickstart.rst

+22-22
Original file line numberDiff line numberDiff line change
@@ -42,14 +42,20 @@ interpreter. Make sure to not call your application :file:`flask.py` because th
4242
would conflict with Flask itself.
4343

4444
To run the application you can either use the :command:`flask` command or
45-
python's :option:`-m` switch with Flask::
45+
python's :option:`-m` switch with Flask. Before you can do that you need
46+
to tell your terminal the application to work with by exporting the
47+
`FLASK_APP` environment variable::
4648

47-
$ flask -a hello run
49+
$ export FLASK_APP=hello.py
50+
$ flask run
4851
* Running on http://127.0.0.1:5000/
4952

50-
or alternatively::
53+
If you are on Windows you need to use `set` instead of `export`.
5154

52-
$ python -m flask -a hello run
55+
Alternatively you can use `python -m flask`::
56+
57+
$ export FLASK_APP=hello.py
58+
$ python -m flask run
5359
* Running on http://127.0.0.1:5000/
5460

5561
This launches a very simple builtin server, which is good enough for testing
@@ -72,7 +78,7 @@ should see your hello world greeting.
7278
you can make the server publicly available simply by adding
7379
``--host=0.0.0.0`` to the command line::
7480

75-
flask -a hello run --host=0.0.0.0
81+
flask run --host=0.0.0.0
7682

7783
This tells your operating system to listen on all public IPs.
7884

@@ -87,28 +93,19 @@ to look at the error message.
8793
Old Version of Flask
8894
````````````````````
8995

90-
Versions of Flask older than 1.0 use to have different ways to start the
96+
Versions of Flask older than 0.11 use to have different ways to start the
9197
application. In short, the :command:`flask` command did not exist, and
9298
neither did ``python -m flask``. In that case you have two options:
9399
either upgrade to newer Flask versions or have a look at the :ref:`server`
94100
docs to see the alternative method for running a server.
95101

96-
Python older 2.7
97-
````````````````
98-
99-
In case you have a version of Python older than 2.7 ``python -m flask``
100-
does not work. You can either use :command:`flask` or ``python -m
101-
flask.cli`` as an alternative. This is because Python before 2.7 does no
102-
permit packages to act as executable modules. For more information see
103-
:ref:`cli`.
104-
105102
Invalid Import Name
106103
```````````````````
107104

108-
The :option:`-a` argument to :command:`flask` is the name of the module to import. In
109-
case that module is incorrectly named you will get an import error upon
110-
start (or if debug is enabled when you navigate to the application). It
111-
will tell you what it tried to import and why it failed.
105+
The :option:`-a` argument to :command:`flask` is the name of the module to
106+
import. In case that module is incorrectly named you will get an import
107+
error upon start (or if debug is enabled when you navigate to the
108+
application). It will tell you what it tried to import and why it failed.
112109

113110
The most common reason is a typo or because you did not actually create an
114111
``app`` object.
@@ -126,10 +123,13 @@ That is not very nice and Flask can do better. If you enable debug
126123
support the server will reload itself on code changes, and it will also
127124
provide you with a helpful debugger if things go wrong.
128125

129-
There are different ways to enable the debug mode. The most obvious one
130-
is the :option:`--debug` parameter to the :command:`flask` command::
126+
To enable debug mode you can export the `FLASK_DEBUG` environment variable
127+
before running the server::
128+
129+
$ export FLASK_DEBUG=1
130+
$ flask run
131131

132-
flask --debug -a hello run
132+
(On Windows you need to use `set` instead of `export`).
133133

134134
This does the following things:
135135

‎docs/tutorial/dbcon.rst

-1
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@ already established connection::
3737
g.sqlite_db = connect_db()
3838
return g.sqlite_db
3939

40-
4140
So now we know how to connect, but how do we properly disconnect? For
4241
that, Flask provides us with the :meth:`~flask.Flask.teardown_appcontext`
4342
decorator. It's executed every time the application context tears down::

‎docs/tutorial/dbinit.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ databases will not commit unless you explicitly tell it to.
6060

6161
Now, it is possible to create a database with the :command:`flask` script::
6262

63-
flask --app=flaskr initdb
63+
flask initdb
6464
Initialized the database.
6565

6666
.. admonition:: Troubleshooting

‎docs/tutorial/setup.rst

+8-5
Original file line numberDiff line numberDiff line change
@@ -91,13 +91,16 @@ tuples.
9191
return rv
9292

9393
With that out of the way, you should be able to start up the application
94-
without problems. Do this with the following command::
94+
without problems. Do this with the following commands::
9595

96-
flask --app=flaskr --debug run
96+
export FLASK_APP=flaskr
97+
export FLASK_DEBUG=1
98+
flask run
9799

98-
The :option:`--debug` flag enables or disables the interactive debugger. *Never
99-
leave debug mode activated in a production system*, because it will allow
100-
users to execute code on the server!
100+
(In case you are on Windows you need to use `set` instead of `export`).
101+
The :envvar:`FLASK_DEBUG` flag enables or disables the interactive debugger.
102+
*Never leave debug mode activated in a production system*, because it will
103+
allow users to execute code on the server!
101104

102105
You will see a message telling you that server has started along with
103106
the address at which you can access it.

‎examples/flaskr/README

+8-4
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,17 @@
1313
export an FLASKR_SETTINGS environment variable
1414
pointing to a configuration file.
1515

16-
2. initialize the database with this command:
16+
2. Instruct flask to use the right application
1717

18-
flask --app=flaskr initdb
18+
export FLASK_APP=flaskr
1919

20-
3. now you can run flaskr:
20+
3. initialize the database with this command:
2121

22-
flask --app=flaskr run
22+
flask initdb
23+
24+
4. now you can run flaskr:
25+
26+
flask run
2327

2428
the application will greet you on
2529
http://localhost:5000/

‎examples/minitwit/README

+6-2
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,17 @@
1414
export an MINITWIT_SETTINGS environment variable
1515
pointing to a configuration file.
1616

17+
2. tell flask about the right application:
18+
19+
export FLASK_APP=minitwit
20+
1721
2. fire up a shell and run this:
1822

19-
flask --app=minitwit initdb
23+
flask initdb
2024

2125
3. now you can run minitwit:
2226

23-
flask --app=minitwit run
27+
flask run
2428

2529
the application will greet you on
2630
http://localhost:5000/

‎flask/cli.py

+16-6
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,10 @@ def __call__(self, environ, start_response):
165165
class ScriptInfo(object):
166166
"""Help object to deal with Flask applications. This is usually not
167167
necessary to interface with as it's used internally in the dispatching
168-
to click.
168+
to click. In future versions of Flask this object will most likely play
169+
a bigger role. Typically it's created automatically by the
170+
:class:`FlaskGroup` but you can also manually create it and pass it
171+
onwards as click object.
169172
"""
170173

171174
def __init__(self, app_import_path=None, create_app=None):
@@ -174,7 +177,10 @@ def __init__(self, app_import_path=None, create_app=None):
174177
app_import_path = find_default_import_path()
175178
self.app_import_path = app_import_path
176179
else:
177-
self.app_import_path = None
180+
app_import_path = None
181+
182+
#: Optionally the import path for the Flask application.
183+
self.app_import_path = app_import_path
178184
#: Optionally a function that is passed the script info to create
179185
#: the instance of the application.
180186
self.create_app = create_app
@@ -194,10 +200,12 @@ def load_app(self):
194200
if self.create_app is not None:
195201
rv = self.create_app(self)
196202
else:
197-
if self.app_import_path is None:
198-
raise NoAppException('Could not locate Flask application. '
199-
'You did not provide the FLASK_APP '
200-
'environment variable.')
203+
if not self.app_import_path:
204+
raise NoAppException(
205+
'Could not locate Flask application. You did not provide '
206+
'the FLASK_APP environment variable.\n\nFor more '
207+
'information see '
208+
'http://flask.pocoo.org/docs/latest/quickstart/')
201209
rv = locate_app(self.app_import_path)
202210
debug = get_debug_flag()
203211
if debug is not None:
@@ -369,6 +377,8 @@ def run_command(info, host, port, reload, debugger, eager_loading,
369377
# we won't print anything.
370378
if info.app_import_path is not None:
371379
print(' * Serving Flask app "%s"' % info.app_import_path)
380+
if debug is not None:
381+
print(' * Forcing debug mode %s' % (debug and 'on' or 'off'))
372382

373383
run_simple(host, port, app, use_reloader=reload,
374384
use_debugger=debugger, threaded=with_threads)

0 commit comments

Comments
 (0)
Please sign in to comment.