Command Line Interface

New in version 1.0.

One of the nice new features in Flask 1.0 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

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 -m flask 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. The two most common ways are either an environment variable (FLASK_APP) or the --app / -a parameter. It should be the import path for your application or the path to a Python file. In the latter case Flask will attempt to setup the Python path for you automatically and discover the module name but that might not always work.

In that imported file the name of the app needs to be called app or optionally be specified after a colon.

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

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

export FLASK_APP=hello
flask run

Parameters:

flask --app=hello run

File names:

flask --app=hello.py run

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

The flask script can be run with --debug or --no-debug to automatically flip the debug flag of the application. This can also be configured by setting FLASK_DEBUG to 1 or 0.

Running a Shell

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

flask --app=hello shell

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.

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:

from flask import Flask

app = Flask(__name__)

@app.cli.command()
def initdb():
    """Initialize the database."""
    print 'Init the db'

The command will then show up on the command line:

$ flask -a hello.py initdb
Init the db

Factory Functions

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 by far 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.

This could be a file named autoapp.py with these contents:

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

From this point onwards flask will find your application.

Custom Scripts

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.

If you are used to writing click applications this will look familiar but at the same time, slightly different because of how commands are loaded. We won’t go into detail now about the differences but if you are curious you can have a look at the The Script Info section to learn all about it.

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:

import click
from flask.cli import FlaskGroup, script_info_option

def create_wiki_app(info):
    from yourwiki import create_app
    config = info.data.get('config') or 'wikiconfig.py'
    return create_app(config=config)

@click.group(cls=FlaskGroup, create_app=create_wiki_app)
@script_info_option('--config', script_info_key='config')
def cli(**params):
    """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 FlaskGroup click group and the script_info_option() decorator.

  2. The next thing we do is defining a function that is invoked with the script info object (The Script Info) 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).

    What is data.info? It’s a dictionary of arbitrary data on the script info that can be filled by options or through other means. We will come back to this later.

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

  4. In step 2 you could see that the config is passed to the actual creation function. This config comes from the script_info_option() decorator for the main script. It accepts a --config option and then stores it in the script info so we can use it to create the application.

  5. All is rounded up by invoking the script.

The Script Info

The Flask script integration might be confusing at first, but there is a reason why it’s done this way. The reason for this is that Flask wants to both provide custom commands to click as well as not loading your application unless it has to. The reason for this is added flexibility.

This way an application can provide custom commands, but even in the absence of an application the flask script is still operational on a basic level. In addition to that it means that the individual commands have the option to avoid creating an instance of the Flask application unless required. This is very useful as it allows the server commands for instance to load the application on a first request instead of immediately, therefore giving a better debug experience.

All of this is provided through the flask.cli.ScriptInfo object and some helper utilities around. The basic way it operates is that when the flask.cli.FlaskGroup executes as a script it creates a script info and keeps it around. From that point onwards modifications on the script info can be done through click options. To simplify this pattern the flask.cli.script_info_option() decorator was added.

One Flask actually needs the individual Flask application it will invoke the flask.cli.ScriptInfo.load_app() method. This happens when the server starts, when the shell is launched or when the script looks for an application-provided click command.