|
|
|
@ -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 <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 |
|
|
|
|
----------- |
|
|
|
|
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 <cli.run_command>` 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 <cli.shell_command>` 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``. |
|
|
|
|