After installation of Flask you will now find a 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-mflask to accomplish
exactly the same.

The way this script works is by providing access to all the commands on
your Flask application’s 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.

For the 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.

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 mymodule.py file.

Given a hello.py file with the application in it named app
this is how it can be run.

If you are constantly working with a virtualenv you can also put the
exportFLASK_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.

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 Flask.make_shell_context() method of the
application. By default you have access to your app and g.

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:

importclickfromflaskimportFlaskapp=Flask(__name__)@app.cli.command()definitdb():"""Initialize the database."""click.echo('Init the db')

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 command() the
callback will automatically be wrapped through 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
add_command() or through other means.

It can also be disabled by passing with_appcontext=False to the
decorator:

In case you are using factory functions to create your application (see
Application Factories) you will discover that the 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
Custom Scripts support.

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.

While the most common way is to use the 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 Flask.cli will expect to be (indirectly at least)
launched from a 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
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 Application 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 manage.py script that
manages a hypothetical wiki application. We will go through the details
afterwards:

importosimportclickfromflask.cliimportFlaskGroupdefcreate_wiki_app(info):fromyourwikiimportcreate_appreturncreate_app(config=os.environ.get('WIKI_CONFIG','wikiconfig.py'))@click.group(cls=FlaskGroup,create_app=create_wiki_app)defcli():"""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.

First we import the click library as well as the click extensions
from the flask.cli package. Primarily we are here interested
in the FlaskGroup click group.

The next thing we do is defining a function that is invoked with the
script info object (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
Application Factories). In this case we load the config from an
environment variable.

Next step is to create a 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.

Flask extensions can always patch the 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 setup.py file
that declares an entrypoint that points to a click command: