diff --git a/docs/cli.rst b/docs/cli.rst
index b481991d..cdb0fc59 100644
--- a/docs/cli.rst
+++ b/docs/cli.rst
@@ -1,145 +1,148 @@
+.. currentmodule:: flask
+
.. _cli:
Command Line Interface
======================
-.. versionadded:: 0.11
+Installing Flask installs the ``flask`` script, a `Click`_ command line
+interface, in your virtualenv. Executed from the terminal, this script gives
+access to built-in, extension, and application-defined commands. The ``--help``
+option will give more information about any commands and options.
-.. currentmodule:: flask
+.. _Click: http://click.pocoo.org/
-One of the nice new features in Flask 0.11 is the built-in integration of
-the `click `_ command line interface. This
-enables a wide range of new features for the Flask ecosystem and your own
-applications.
-Basic Usage
------------
+Application Discovery
+---------------------
-After installation of Flask you will now find a :command:`flask` script
-installed into your virtualenv. If you don't want to install Flask or you
-have a special use-case you can also use ``python -m flask`` to accomplish
-exactly the same.
+The ``flask`` command is installed by Flask, not your application; it must be
+told where to find your application in order to use it. The ``FLASK_APP``
+environment variable is used to specify how to load the application.
-The way this script works is by providing access to all the commands on
-your Flask application's :attr:`Flask.cli` instance as well as some
-built-in commands that are always there. Flask extensions can also
-register more commands there if they desire so.
+Unix Bash (Linux, Mac, etc.)::
-For the :command:`flask` script to work, an application needs to be discovered.
-Flask looks for a module named :file:`wsgi.py` or :file:`app.py` by default,
-and if it finds one it assumes the application is defined in it.
+ $ export FLASK_APP=hello
+ $ flask run
-You can instruct Flask to look for the application in a different module by
-exporting the ``FLASK_APP`` environment variable. It can be either set to an
-import path or to a filename of a Python module that contains a Flask
-application.
+Windows CMD::
-In that imported file the name of the app needs to be called ``app`` or
-optionally be specified after a colon. For instance
-``mymodule:application`` would tell it to use the `application` object in
-the :file:`mymodule.py` file.
+ > set FLASK_APP=hello
+ > flask run
-Given a :file:`hello.py` file with the application in it named ``app``
-this is how it can be run.
+Windows PowerShell::
-Environment variables (On Windows use ``set`` instead of ``export``)::
+ > $env:FLASK_APP = "hello"
+ > flask run
- export FLASK_APP=hello
- flask run
+While ``FLASK_APP`` supports a variety of options for specifying your
+application, most use cases should be simple. Here are the typical values:
-Or with a filename::
+(nothing)
+ The file :file:`wsgi.py` is imported, automatically detecting an app
+ (``app``). This provides an easy way to create an app from a factory with
+ extra arguments.
- export FLASK_APP=/path/to/hello.py
- flask run
+``FLASK_APP=hello``
+ The name is imported, automatically detecting an app (``app``) or factory
+ (``create_app``).
-Virtualenv Integration
-----------------------
+----
-If you are constantly working with a virtualenv you can also put the
-``export FLASK_APP`` into your ``activate`` script by adding it to the
-bottom of the file. That way every time you activate your virtualenv you
-automatically also activate the correct application name.
+``FLASK_APP`` has three parts: an optional path that sets the current working
+directory, a Python file or dotted import path, and an optional variable
+name of the instance or factory. If the name is a factory, it can optionally
+be followed by arguments in parentheses. The following values demonstrate these
+parts:
-Edit the activate script for the shell you use. For example:
+``FLASK_APP=src/hello``
+ Sets the current working directory to ``src`` then imports ``hello``.
-Unix Bash: ``venv/bin/activate``::
+``FLASK_APP=hello.web``
+ Imports the path ``hello.web``.
- FLASK_APP=hello
- export FLASK_APP
+``FLASK_APP=hello:app2``
+ Uses the ``app2`` Flask instance in ``hello``.
-Windows CMD.exe: ``venv\Scripts\activate.bat``::
+``FLASK_APP="hello:create_app('dev')"``
+ The ``create_app`` factory in ``hello`` is called with the string ``'dev'``
+ as the argument.
- set "FLASK_APP=hello"
- :END
+If ``FLASK_APP`` is not set, the command will look for a file called
+:file:`wsgi.py` or :file:`app.py` and try to detect an application instance or
+factory.
-Debug Flag
-----------
+Within the given import, the command looks for an application instance named
+``app`` or ``application``, then any application instance. If no instance is
+found, the command looks for a factory function named ``create_app`` or
+``make_app`` that returns an instance.
-The :command:`flask` script can also be instructed to enable the debug
-mode of the application automatically by exporting ``FLASK_DEBUG``. If
-set to ``1`` debug is enabled or ``0`` disables it::
+When calling an application factory, if the factory takes an argument named
+``info``, then the :class:`~cli.ScriptInfo` instance is passed as a keyword
+argument. If parentheses follow the factory name, their contents are parsed
+as Python literals and passes as arguments to the function. This means that
+strings must still be in quotes.
- export FLASK_DEBUG=1
-Running a Shell
----------------
+Run the Development Server
+--------------------------
-To run an interactive Python shell you can use the ``shell`` command::
+The :func:`run ` command will start the development server. It
+replaces the :meth:`Flask.run` method in most cases. ::
- flask shell
+ $ flask run
+ * Serving Flask app "hello"
+ * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
-This will start up an interactive Python shell, setup the correct
-application context and setup the local variables in the shell. This is
-done by invoking the :meth:`Flask.make_shell_context` method of the
-application. By default you have access to your ``app`` and :data:`g`.
+.. warning:: Do not use this command to run your application in production.
+ Only use the development server during development. The development server
+ is provided for convenience, but is not designed to be particularly secure,
+ stable, or efficient. See :ref:`deployment` for how to run in production.
-Custom Commands
----------------
-
-If you want to add more commands to the shell script you can do this
-easily. For instance if you want a shell command to initialize the database you
-can do this::
-
- import click
- from flask import Flask
- app = Flask(__name__)
+Open a Shell
+------------
- @app.cli.command()
- def initdb():
- """Initialize the database."""
- click.echo('Init the db')
+To explore the data in your application, you can start an interactive Python
+shell with the :func:`shell ` command. An application
+context will be active, and the app instance will be imported. ::
-The command will then show up on the command line::
+ $ flask shell
+ Python 3.6.2 (default, Jul 20 2017, 03:52:27)
+ [GCC 7.1.1 20170630] on linux
+ App: example
+ Instance: /home/user/Projects/hello/instance
+ >>>
- $ flask initdb
- Init the db
+Use :meth:`~Flask.shell_context_processor` to add other automatic imports.
-Application Context
--------------------
-Most commands operate on the application so it makes a lot of sense if
-they have the application context setup. Because of this, if you register
-a callback on ``app.cli`` with the :meth:`~flask.cli.AppGroup.command` the
-callback will automatically be wrapped through :func:`cli.with_appcontext`
-which informs the cli system to ensure that an application context is set
-up. This behavior is not available if a command is added later with
-:func:`~click.Group.add_command` or through other means.
+Debug Mode
+----------
-It can also be disabled by passing ``with_appcontext=False`` to the
-decorator::
+Set the :envvar:`FLASK_DEBUG` environment variable to override the
+application's :attr:`~Flask.debug` flag. The value ``1`` enables it, ``0``
+disables it. Forcing the debug flag on also enables the debugger and reloader
+when running the development server. ::
- @app.cli.command(with_appcontext=False)
- def example():
- pass
+ $ FLASK_DEBUG=1 flask run
+ * Serving Flask app "hello"
+ * Forcing debug mode on
+ * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
+ * Restarting with inotify reloader
+ * Debugger is active!
+ * Debugger PIN: 223-456-919
.. _dotenv:
-Loading Environment Variables From ``.env`` Files
--------------------------------------------------
+Environment Variables From dotenv
+---------------------------------
+
+Rather than setting ``FLASK_APP`` each time you open a new terminal, you can
+use Flask's dotenv support to set environment variables automatically.
-If `python-dotenv`_ is installed, running the :command:`flask` command will set
+If `python-dotenv`_ is installed, running the ``flask`` command will set
environment variables defined in the files :file:`.env` and :file:`.flaskenv`.
This can be used to avoid having to set ``FLASK_APP`` manually every time you
open a new terminal, and to set configuration using environment variables
@@ -150,186 +153,231 @@ which are used over those set in :file:`.flaskenv`. :file:`.flaskenv` should be
used for public variables, such as ``FLASK_APP``, while :file:`.env` should not
be committed to your repository so that it can set private variables.
-Directories are scanned upwards from the directory you call :command:`flask`
+Directories are scanned upwards from the directory you call ``flask``
from to locate the files. The current working directory will be set to the
location of the file, with the assumption that that is the top level project
directory.
-The files are only loaded by the :command:`flask` command or calling
-:meth:`~flask.Flask.run`. If you would like to load these files when running in
-production, you should call :func:`~flask.cli.load_dotenv` manually.
+The files are only loaded by the ``flask`` command or calling
+:meth:`~Flask.run`. If you would like to load these files when running in
+production, you should call :func:`~cli.load_dotenv` manually.
.. _python-dotenv: https://github.com/theskumar/python-dotenv#readme
-Factory Functions
------------------
+Environment Variables From virtualenv
+-------------------------------------
+
+If you do not want to install dotenv support, you can still set environment
+variables by adding them to the end of the virtualenv's :file:`activate`
+script. Activating the virtualenv will set the variables.
+
+Unix Bash, :file:`venv/bin/activate`::
+
+ export FLASK_APP=hello
+
+Windows CMD, :file:`venv\Scripts\activate.bat`::
+
+ set FLASK_APP=hello
+
+It is preferred to use dotenv support over this, since :file:`.flaskenv` can be
+committed to the repository so that it works automatically wherever the project
+is checked out.
+
+
+Custom Commands
+---------------
+
+The ``flask`` command is implemented using `Click`_. See that project's
+documentation for full information about writing commands.
+
+This example adds the command ``create_user`` that takes the argument
+``name``. ::
+
+ import click
+ from flask import Flask
-In case you are using factory functions to create your application (see
-:ref:`app-factories`) you will discover that the :command:`flask` command
-cannot work with them directly. Flask won't be able to figure out how to
-instantiate your application properly by itself. Because of this reason
-the recommendation is to create a separate file that instantiates
-applications. This is not the only way to make this work. Another is the
-:ref:`custom-scripts` support.
+ app = Flask(__name__)
-For instance if you have a factory function that creates an application
-from a filename you could make a separate file that creates such an
-application from an environment variable.
+ @app.cli.command()
+ @click.argument('name')
+ def create_user(name):
+ ...
-This could be a file named :file:`autoapp.py` with these contents::
+::
- import os
- from yourapplication import create_app
- app = create_app(os.environ['YOURAPPLICATION_CONFIG'])
+ flask create_user admin
-Once this has happened you can make the :command:`flask` command automatically
-pick it up::
+This example adds the same command, but as ``user create``, a command in a
+group. This is useful if you want to organize multiple related commands. ::
- export YOURAPPLICATION_CONFIG=/path/to/config.cfg
- export FLASK_APP=/path/to/autoapp.py
+ import click
+ from flask import Flask
+ from flask.cli import AppGroup
+
+ app = Flask(__name__)
+ user_cli = AppGroup('user')
+
+ @user_cli.command('create')
+ @click.argument('name')
+ def create_user(name):
+ ...
+
+ app.cli.add_command(user_cli)
+
+::
+
+ flask user create demo
+
+
+Application Context
+~~~~~~~~~~~~~~~~~~~
+
+Commands added using the Flask app's :attr:`~Flask.cli`
+:meth:`~cli.AppGroup.command` decorator will be executed with an application
+context pushed, so your command and extensions have access to the app and its
+configuration. If you create a command using the Click :func:`~click.command`
+decorator instead of the Flask decorator, you can use
+:func:`~cli.with_appcontext` to get the same behavior. ::
+
+ import click
+ from flask.cli import with_appcontext
+
+ @click.command
+ @with_appcontext
+ def do_work():
+ ...
+
+ app.cli.add_command(do_work)
+
+If you're sure a command doesn't need the context, you can disable it::
+
+ @app.cli.command(with_appcontext=False)
+ def do_work():
+ ...
+
+
+Plugins
+-------
+
+Flask will automatically load commands specified in the ``flask.commands``
+`entry point`_. This is useful for extensions that want to add commands when
+they are installed. Entry points are specified in :file:`setup.py` ::
+
+ from setuptools import setup
+
+ setup(
+ name='flask-my-extension',
+ ...,
+ entry_points={
+ 'flask.commands': [
+ 'my-command=flask_my_extension.commands:cli'
+ ],
+ },
+ )
+
+
+.. _entry point: https://packaging.python.org/tutorials/distributing-packages/#entry-points
+
+Inside :file:`flask_my_extension/commands.py` you can then export a Click
+object::
+
+ import click
+
+ @click.command()
+ def cli():
+ ...
+
+Once that package is installed in the same virtualenv as your Flask project,
+you can run ``flask my-command`` to invoke the command.
-From this point onwards :command:`flask` will find your application.
.. _custom-scripts:
Custom Scripts
--------------
-While the most common way is to use the :command:`flask` command, you can
-also make your own "driver scripts". Since Flask uses click for the
-scripts there is no reason you cannot hook these scripts into any click
-application. There is one big caveat and that is, that commands
-registered to :attr:`Flask.cli` will expect to be (indirectly at least)
-launched from a :class:`flask.cli.FlaskGroup` click group. This is
-necessary so that the commands know which Flask application they have to
-work with.
-
-To understand why you might want custom scripts you need to understand how
-click finds and executes the Flask application. If you use the
-:command:`flask` script you specify the application to work with on the
-command line or environment variable as an import name. This is simple
-but it has some limitations. Primarily it does not work with application
-factory functions (see :ref:`app-factories`).
-
-With a custom script you don't have this problem as you can fully
-customize how the application will be created. This is very useful if you
-write reusable applications that you want to ship to users and they should
-be presented with a custom management script.
-
-To explain all of this, here is an example :file:`manage.py` script that
-manages a hypothetical wiki application. We will go through the details
-afterwards::
-
- import os
+When you are using the app factory pattern, it may be more convenient to define
+your own Click script. Instead of using ``FLASK_APP`` and letting Flask load
+your application, you can create your own Click object and export it as a
+`console script`_ entry point.
+
+Create an instance of :class:`~cli.FlaskGroup` and pass it the factory::
+
import click
+ from flask import Flask
from flask.cli import FlaskGroup
- def create_wiki_app(info):
- from yourwiki import create_app
- return create_app(
- config=os.environ.get('WIKI_CONFIG', 'wikiconfig.py'))
+ def create_app():
+ app = Flask('wiki')
+ # other setup
+ return app
- @click.group(cls=FlaskGroup, create_app=create_wiki_app)
+ @click.group(cls=FlaskGroup, create_app=create_app)
def cli():
- """This is a management script for the wiki application."""
-
- if __name__ == '__main__':
- cli()
-
-That's a lot of code for not much, so let's go through all parts step by
-step.
-
-1. First we import the ``click`` library as well as the click extensions
- from the ``flask.cli`` package. Primarily we are here interested
- in the :class:`~flask.cli.FlaskGroup` click group.
-2. The next thing we do is defining a function that is invoked with the
- script info object (:class:`~flask.cli.ScriptInfo`) from Flask and its
- purpose is to fully import and create the application. This can
- either directly import an application object or create it (see
- :ref:`app-factories`). In this case we load the config from an
- environment variable.
-3. Next step is to create a :class:`FlaskGroup`. In this case we just
- make an empty function with a help doc string that just does nothing
- and then pass the ``create_wiki_app`` function as a factory function.
-
- Whenever click now needs to operate on a Flask application it will
- call that function with the script info and ask for it to be created.
-4. All is rounded up by invoking the script.
-
-CLI Plugins
------------
-
-Flask extensions can always patch the :attr:`Flask.cli` instance with more
-commands if they want. However there is a second way to add CLI plugins
-to Flask which is through ``setuptools``. If you make a Python package that
-should export a Flask command line plugin you can ship a :file:`setup.py` file
-that declares an entrypoint that points to a click command:
-
-Example :file:`setup.py`::
+ """Management script for the Wiki application."""
+
+Define the entry point in :file:`setup.py`::
from setuptools import setup
setup(
name='flask-my-extension',
- ...
- entry_points='''
- [flask.commands]
- my-command=mypackage.commands:cli
- ''',
+ ...,
+ entry_points={
+ 'console_scripts': [
+ 'wiki=wiki:cli'
+ ],
+ },
)
-Inside :file:`mypackage/commands.py` you can then export a Click object::
+Install the application in the virtualenv in editable mode and the custom
+script is available. Note that you don't need to set ``FLASK_APP``. ::
- import click
+ $ pip install -e .
+ $ wiki run
- @click.command()
- def cli():
- """This is an example command."""
+.. _console script: https://packaging.python.org/tutorials/distributing-packages/#console-scripts
-Once that package is installed in the same virtualenv as Flask itself you
-can run ``flask my-command`` to invoke your command. This is useful to
-provide extra functionality that Flask itself cannot ship.
PyCharm Integration
-------------------
-The new Flask CLI features aren’t yet fully integrated into the PyCharm IDE,
-so we have to do a few tweaks to get them working smoothly.
+The new Flask CLI features aren't yet fully integrated into the PyCharm IDE,
+so we have to do a few tweaks to get them working smoothly. These instructions
+should be similar for any other IDE you might want to use.
-In your PyCharm application, with your project open, click on *Run*
-from the menu bar and go to *Edit Configurations*. You’ll be greeted by a
-screen similar to this:
+In PyCharm, with your project open, click on *Run* from the menu bar and go to
+*Edit Configurations*. You'll be greeted by a screen similar to this:
.. image:: _static/pycharm-runconfig.png
:align: center
:class: screenshot
:alt: screenshot of pycharm's run configuration settings
-There’s quite a few options to change, but don’t worry— once we’ve done it
-for one command, we can easily copy the entire configuration and make a
-single tweak to give us access to other flask cli commands, including
-any custom ones you may implement yourself.
+There's quite a few options to change, but once we've done it for one command,
+we can easily copy the entire configuration and make a single tweak to give us
+access to other commands, including any custom ones you may implement yourself.
-For the *Script* input (**A**), we want to navigate to the virtual environment
-we’re using for our project and within that folder we want to pick the ``flask``
-file which will reside in the ``bin`` folder, or in the ``Scripts`` folder if
-you're on Windows.
+For the *Script* input (**A**), navigate to your project's virtual environment.
+Within that folder, pick the ``flask`` executable which will reside in the
+``bin`` folder, or in the ``Scripts`` on Windows.
-The *Script Parameter* field (**B**) is set to the cli command you wish to
-execute, in this example we use ``run`` which will run our development server.
+The *Script Parameter* field (**B**) is set to the CLI command you to execute.
+In this example we use ``run``, which will run the development server.
-We need to add an environment variable (**C**) to identify our application.
-Click on the browse button and add an entry with ``FLASK_APP`` on the
-left and the name of the python file, or package on the right
-(``app.py`` for example).
+You can skip this next step if you're using :ref:`dotenv`. We need to add an
+environment variable (**C**) to identify our application. Click on the browse
+button and add an entry with ``FLASK_APP`` on the left and the name of the
+Python file or package on the right (``app.py`` for example).
Next we need to set the working directory (**D**) to be the same folder where
-our application file or package resides.
+our application file or package resides. PyCharm changed it to the directory
+with the ``flask`` executable when we selected it earlier, which is incorrect.
Finally, untick the *PYTHONPATH* options (**E**) and give the configuration a
-good descriptive name, such as “Run Flask Server” and click *Apply*.
+good descriptive name, such as "Run Flask Server", and click *Apply*.
-Now that we have on run configuration which implements ``flask run`` from within
-PyCharm, we can simply copy that configuration and alter the script argument
-to run a different cli command, e.g. ``flask shell``.
+Now that we have a configuration which runs ``flask run`` from within PyCharm,
+we can simply copy that configuration and alter the *Script* argument
+to run a different CLI command, e.g. ``flask shell``.
diff --git a/docs/installation.rst b/docs/installation.rst
index 0ae05f06..370ce48c 100644
--- a/docs/installation.rst
+++ b/docs/installation.rst
@@ -43,10 +43,13 @@ use them if you install them.
installed.
* `python-dotenv`_ enables support for :ref:`dotenv` when running ``flask``
commands.
+* `Watchdog`_ provides a faster, more efficient reloader for the development
+ server.
.. _Blinker: https://pythonhosted.org/blinker/
.. _SimpleJSON: https://simplejson.readthedocs.io/
.. _python-dotenv: https://github.com/theskumar/python-dotenv#readme
+.. _watchdog: https://pythonhosted.org/watchdog/
Virtual environments
--------------------
diff --git a/flask/cli.py b/flask/cli.py
index 98056e27..d4647401 100644
--- a/flask/cli.py
+++ b/flask/cli.py
@@ -234,11 +234,16 @@ def get_version(ctx, param, value):
}, color=ctx.color)
ctx.exit()
-version_option = click.Option(['--version'],
- help='Show the flask version',
- expose_value=False,
- callback=get_version,
- is_flag=True, is_eager=True)
+
+version_option = click.Option(
+ ['--version'],
+ help='Show the flask version',
+ expose_value=False,
+ callback=get_version,
+ is_flag=True,
+ is_eager=True
+)
+
class DispatchingApp(object):
"""Special application that dispatches to a Flask application which
@@ -713,24 +718,21 @@ def routes_command(sort, all_methods):
cli = FlaskGroup(help="""\
-This shell command acts as general utility script for Flask applications.
-
-It loads the application configured (through the FLASK_APP environment
-variable) and then provides commands either provided by the application or
-Flask itself.
-
-The most useful commands are the "run" and "shell" command.
+A general utility script for Flask applications.
-Example usage:
+Provides commands from Flask, extensions, and the application. Loads the
+application defined in the FLASK_APP environment variable, or from a wsgi.py
+file. Debug mode can be controlled with the FLASK_DEBUG
+environment variable.
\b
- %(prefix)s%(cmd)s FLASK_APP=hello.py
- %(prefix)s%(cmd)s FLASK_DEBUG=1
- %(prefix)sflask run
-""" % {
- 'cmd': os.name == 'posix' and 'export' or 'set',
- 'prefix': os.name == 'posix' and '$ ' or '',
-})
+ {prefix}{cmd} FLASK_APP=hello.py
+ {prefix}{cmd} FLASK_DEBUG=1
+ {prefix}flask run
+""".format(
+ cmd='export' if os.name == 'posix' else 'set',
+ prefix='$ ' if os.name == 'posix' else '> '
+))
def main(as_module=False):