| 
									
										
										
										
											2014-04-28 19:31:21 +08:00
										 |  |  | .. _cli:
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Command Line Interface
 | 
					
						
							|  |  |  | ======================
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-23 20:42:42 +08:00
										 |  |  | .. versionadded:: 0.11
 | 
					
						
							| 
									
										
										
										
											2014-04-28 19:31:21 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | .. currentmodule:: flask
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-27 02:52:17 +08:00
										 |  |  | One of the nice new features in Flask 0.11 is the built-in integration of
 | 
					
						
							| 
									
										
										
										
											2014-04-28 19:31:21 +08:00
										 |  |  | the `click <http://click.pocoo.org/>`_ command line interface.  This
 | 
					
						
							|  |  |  | enables a wide range of new features for the Flask ecosystem and your own
 | 
					
						
							|  |  |  | applications.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Basic Usage
 | 
					
						
							|  |  |  | -----------
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-27 02:45:50 +08:00
										 |  |  | 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.
 | 
					
						
							| 
									
										
										
										
											2014-04-28 19:31:21 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 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
 | 
					
						
							| 
									
										
										
										
											2014-05-08 04:32:43 +08:00
										 |  |  | register more commands there if they desire so.
 | 
					
						
							| 
									
										
										
										
											2014-04-28 19:31:21 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-27 02:45:50 +08:00
										 |  |  | For the :command:`flask` script to work, an application needs to be
 | 
					
						
							|  |  |  | discovered.  This is achieved 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.
 | 
					
						
							| 
									
										
										
										
											2014-04-28 19:31:21 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | In that imported file the name of the app needs to be called ``app`` or
 | 
					
						
							| 
									
										
										
										
											2016-05-27 02:45:50 +08:00
										 |  |  | optionally be specified after a colon.  For instance
 | 
					
						
							| 
									
										
										
										
											2016-06-27 04:03:29 +08:00
										 |  |  | ``mymodule:application`` would tell it to use the `application` object in
 | 
					
						
							| 
									
										
										
										
											2016-05-27 02:45:50 +08:00
										 |  |  | the :file:`mymodule.py` file.
 | 
					
						
							| 
									
										
										
										
											2014-04-28 19:31:21 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-27 02:45:50 +08:00
										 |  |  | Given a :file:`hello.py` file with the application in it named ``app``
 | 
					
						
							|  |  |  | this is how it can be run.
 | 
					
						
							| 
									
										
										
										
											2014-04-28 19:31:21 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | Environment variables (On Windows use ``set`` instead of ``export``)::
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     export FLASK_APP=hello
 | 
					
						
							|  |  |  |     flask run
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-27 02:45:50 +08:00
										 |  |  | Or with a filename::
 | 
					
						
							| 
									
										
										
										
											2014-04-28 19:31:21 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-27 02:45:50 +08:00
										 |  |  |     export FLASK_APP=/path/to/hello.py
 | 
					
						
							|  |  |  |     flask run
 | 
					
						
							| 
									
										
										
										
											2014-04-28 19:31:21 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 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.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Debug Flag
 | 
					
						
							|  |  |  | ----------
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-27 02:45:50 +08:00
										 |  |  | 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.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Or with a filename::
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     export FLASK_DEBUG=1
 | 
					
						
							| 
									
										
										
										
											2014-04-28 19:31:21 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | Running a Shell
 | 
					
						
							|  |  |  | ---------------
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | To run an interactive Python shell you can use the ``shell`` command::
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-27 02:45:50 +08:00
										 |  |  |     flask shell
 | 
					
						
							| 
									
										
										
										
											2014-04-28 19:31:21 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 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`.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Custom Commands
 | 
					
						
							|  |  |  | ---------------
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | If you want to add more commands to the shell script you can do this
 | 
					
						
							|  |  |  | easily.  Flask uses `click`_ for the command interface which makes
 | 
					
						
							|  |  |  | creating custom commands very easy.  For instance if you want a shell
 | 
					
						
							|  |  |  | command to initialize the database you can do this::
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-27 02:45:50 +08:00
										 |  |  |     import click
 | 
					
						
							| 
									
										
										
										
											2014-04-28 19:31:21 +08:00
										 |  |  |     from flask import Flask
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     app = Flask(__name__)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     @app.cli.command()
 | 
					
						
							|  |  |  |     def initdb():
 | 
					
						
							|  |  |  |         """Initialize the database."""
 | 
					
						
							| 
									
										
										
										
											2016-05-27 02:45:50 +08:00
										 |  |  |         click.echo('Init the db')
 | 
					
						
							| 
									
										
										
										
											2014-04-28 19:31:21 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | The command will then show up on the command line::
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-27 02:45:50 +08:00
										 |  |  |     $ flask initdb
 | 
					
						
							| 
									
										
										
										
											2014-04-28 19:31:21 +08:00
										 |  |  |     Init the db
 | 
					
						
							| 
									
										
										
										
											2014-04-29 07:03:32 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-25 22:50:22 +08:00
										 |  |  | 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
 | 
					
						
							| 
									
										
										
										
											2014-10-25 18:14:01 +08:00
										 |  |  | up.  This behavior is not available if a command is added later with
 | 
					
						
							| 
									
										
										
										
											2014-08-25 22:50:22 +08:00
										 |  |  | :func:`~click.Group.add_command` or through other means.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | It can also be disabled by passing ``with_appcontext=False`` to the
 | 
					
						
							|  |  |  | decorator::
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     @app.cli.command(with_appcontext=False)
 | 
					
						
							|  |  |  |     def example():
 | 
					
						
							|  |  |  |         pass
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-29 07:03:32 +08:00
										 |  |  | Factory Functions
 | 
					
						
							|  |  |  | -----------------
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | In case you are using factory functions to create your application (see
 | 
					
						
							| 
									
										
										
										
											2016-05-27 02:45:50 +08:00
										 |  |  | :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
 | 
					
						
							| 
									
										
										
										
											2014-05-08 04:32:43 +08:00
										 |  |  | instantiate your application properly by itself.  Because of this reason
 | 
					
						
							|  |  |  | the recommendation is to create a separate file that instantiates
 | 
					
						
							| 
									
										
										
										
											2016-05-27 02:45:50 +08:00
										 |  |  | applications.  This is not the only way to make this work.  Another is the
 | 
					
						
							|  |  |  | :ref:`custom-scripts` support.
 | 
					
						
							| 
									
										
										
										
											2014-04-29 07:03:32 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 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.
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-05 11:45:22 +08:00
										 |  |  | This could be a file named :file:`autoapp.py` with these contents::
 | 
					
						
							| 
									
										
										
										
											2014-04-29 07:03:32 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     import os
 | 
					
						
							|  |  |  |     from yourapplication import create_app
 | 
					
						
							|  |  |  |     app = create_app(os.environ['YOURAPPLICATION_CONFIG'])
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Once this has happened you can make the flask command automatically pick
 | 
					
						
							|  |  |  | it up::
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     export YOURAPPLICATION_CONFIG=/path/to/config.cfg
 | 
					
						
							|  |  |  |     export FLASK_APP=/path/to/autoapp.py
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-05 12:03:55 +08:00
										 |  |  | From this point onwards :command:`flask` will find your application.
 | 
					
						
							| 
									
										
										
										
											2014-05-08 03:35:51 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | .. _custom-scripts:
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Custom Scripts
 | 
					
						
							|  |  |  | --------------
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-27 02:45:50 +08:00
										 |  |  | 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
 | 
					
						
							| 
									
										
										
										
											2014-05-08 03:35:51 +08:00
										 |  |  | 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
 | 
					
						
							| 
									
										
										
										
											2016-05-27 02:45:50 +08:00
										 |  |  | 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`).
 | 
					
						
							| 
									
										
										
										
											2014-05-08 03:35:51 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 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.
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-05 11:45:22 +08:00
										 |  |  | To explain all of this, here is an example :file:`manage.py` script that
 | 
					
						
							| 
									
										
										
										
											2014-05-08 04:32:43 +08:00
										 |  |  | manages a hypothetical wiki application.  We will go through the details
 | 
					
						
							| 
									
										
										
										
											2014-05-08 03:35:51 +08:00
										 |  |  | afterwards::
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-27 02:45:50 +08:00
										 |  |  |     import os
 | 
					
						
							| 
									
										
										
										
											2014-05-08 03:35:51 +08:00
										 |  |  |     import click
 | 
					
						
							| 
									
										
										
										
											2016-05-27 02:45:50 +08:00
										 |  |  |     from flask.cli import FlaskGroup
 | 
					
						
							| 
									
										
										
										
											2014-05-08 03:35:51 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def create_wiki_app(info):
 | 
					
						
							|  |  |  |         from yourwiki import create_app
 | 
					
						
							| 
									
										
										
										
											2016-05-27 02:45:50 +08:00
										 |  |  |         return create_app(
 | 
					
						
							|  |  |  |             config=os.environ.get('WIKI_CONFIG', 'wikiconfig.py'))
 | 
					
						
							| 
									
										
										
										
											2014-05-08 03:35:51 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     @click.group(cls=FlaskGroup, create_app=create_wiki_app)
 | 
					
						
							| 
									
										
										
										
											2016-05-27 02:45:50 +08:00
										 |  |  |     def cli():
 | 
					
						
							| 
									
										
										
										
											2014-05-08 03:35:51 +08:00
										 |  |  |         """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.
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-08 04:32:43 +08:00
										 |  |  | 1.  First we import the ``click`` library as well as the click extensions
 | 
					
						
							| 
									
										
										
										
											2014-05-08 03:35:51 +08:00
										 |  |  |     from the ``flask.cli`` package.  Primarily we are here interested
 | 
					
						
							| 
									
										
										
										
											2016-05-27 02:45:50 +08:00
										 |  |  |     in the :class:`~flask.cli.FlaskGroup` click group.
 | 
					
						
							| 
									
										
										
										
											2014-05-08 03:35:51 +08:00
										 |  |  | 2.  The next thing we do is defining a function that is invoked with the
 | 
					
						
							| 
									
										
										
										
											2016-05-27 02:45:50 +08:00
										 |  |  |     script info object (:class:`~flask.cli.ScriptInfo`) from Flask and its
 | 
					
						
							| 
									
										
										
										
											2014-05-08 03:35:51 +08:00
										 |  |  |     purpose is to fully import and create the application.  This can
 | 
					
						
							|  |  |  |     either directly import an application object or create it (see
 | 
					
						
							| 
									
										
										
										
											2016-05-27 02:45:50 +08:00
										 |  |  |     :ref:`app-factories`).  In this case we load the config from an
 | 
					
						
							|  |  |  |     environment variable.
 | 
					
						
							| 
									
										
										
										
											2014-05-08 03:35:51 +08:00
										 |  |  | 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
 | 
					
						
							| 
									
										
										
										
											2014-05-08 04:32:43 +08:00
										 |  |  |     and then pass the ``create_wiki_app`` function as a factory function.
 | 
					
						
							| 
									
										
										
										
											2014-05-08 03:35:51 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-08 04:32:43 +08:00
										 |  |  |     Whenever click now needs to operate on a Flask application it will
 | 
					
						
							| 
									
										
										
										
											2014-05-08 03:35:51 +08:00
										 |  |  |     call that function with the script info and ask for it to be created.
 | 
					
						
							| 
									
										
										
										
											2016-05-27 02:45:50 +08:00
										 |  |  | 4.  All is rounded up by invoking the script.
 | 
					
						
							| 
									
										
										
										
											2016-05-27 03:29:01 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | CLI Plugins
 | 
					
						
							|  |  |  | -----------
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-27 04:03:29 +08:00
										 |  |  | Flask extensions can always patch the :attr:`Flask.cli` instance with more
 | 
					
						
							| 
									
										
										
										
											2016-05-27 03:29:01 +08:00
										 |  |  | commands if they want.  However there is a second way to add CLI plugins
 | 
					
						
							| 
									
										
										
										
											2016-06-27 04:03:29 +08:00
										 |  |  | 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
 | 
					
						
							| 
									
										
										
										
											2016-05-27 03:29:01 +08:00
										 |  |  | that declares an entrypoint that points to a click command:
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-27 04:03:29 +08:00
										 |  |  | Example :file:`setup.py`::
 | 
					
						
							| 
									
										
										
										
											2016-05-27 03:29:01 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     from setuptools import setup
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     setup(
 | 
					
						
							|  |  |  |         name='flask-my-extension',
 | 
					
						
							|  |  |  |         ...
 | 
					
						
							|  |  |  |         entry_points='''
 | 
					
						
							|  |  |  |             [flask.commands]
 | 
					
						
							|  |  |  |             my-command=mypackage.commands:cli
 | 
					
						
							|  |  |  |         ''',
 | 
					
						
							|  |  |  |     )
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-27 04:03:29 +08:00
										 |  |  | Inside :file:`mypackage/commands.py` you can then export a Click object::
 | 
					
						
							| 
									
										
										
										
											2016-05-27 03:29:01 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     import click
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     @click.command()
 | 
					
						
							|  |  |  |     def cli():
 | 
					
						
							|  |  |  |         """This is an example command."""
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 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.
 |