I have a python package using a click
group to have multiple command line subcommands.
In addition to this, I would like to have a small flask application.
The other subcommands are the primary function of the package - not the flask application. As such, I would like the flask commands to be nested under their own group.
I made a minimal example to demonstrate my problem - it's on GitHub here: https://github.com/ewels/flask-subcommand-issue
In the minimal example, I set up a mini flask installation that runs with the fsksc_server
command.
This is thanks to a setuptools console_scripts
entry point hook in setup.py
.
The command works perfectly, exactly as you would expect:
$ fsksc_server --help
Usage: fsksc_server [OPTIONS] COMMAND [ARGS]...
Run the fsksc server flask app
Options:
--version Show the flask version
--help Show this message and exit.
Commands:
routes Show the routes for the app.
run Runs a development server.
shell Runs a shell in the app context.
$ fsksc_server run
* Environment: production
WARNING: Do not use the development server in a production environment.
Use a production WSGI server instead.
* Debug mode: off
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
(I haven't set up any routes, so visiting the URL throws a 404, but the server is running fine..)
To get the flask commands in a click subcommand I have used flask add_command
with the flask group.
This main command is fsksc
. The flask subcommand should be shell
.
The intention is to make fsksc shell run
launch the development server.
The commands show up properly, so this part seems to work:
$ fsksc --help
Usage: fsksc [OPTIONS] COMMAND [ARGS]...
Options:
--help Show this message and exit.
Commands:
cmd1
cmd2
server Run the fsksc server flask app
When doing anything under the server
subcommand, I get a warning message about a NoAppException
exception:
$ fsksc server --help
Traceback (most recent call last):
File "/Users/ewels/miniconda2/envs/work/lib/python2.7/site-packages/Flask-1.0.2-py2.7.egg/flask/cli.py", line 529, in list_commands
rv.update(info.load_app().cli.list_commands(ctx))
File "/Users/ewels/miniconda2/envs/work/lib/python2.7/site-packages/Flask-1.0.2-py2.7.egg/flask/cli.py", line 384, in load_app
'Could not locate a Flask application. You did not provide '
NoAppException: Could not locate a Flask application. You did not provide the "FLASK_APP" environment variable, and a "wsgi.py" or "app.py" module was not found in the current directory.
Usage: fsksc server [OPTIONS] COMMAND [ARGS]...
Run the fsksc server flask app
Options:
--version Show the flask version
--help Show this message and exit.
Commands:
routes Show the routes for the app.
run Runs a development server.
shell Runs a shell in the app context.
Trying to run the server gives a similar error:
$ fsksc server run
* Environment: production
WARNING: Do not use the development server in a production environment.
Use a production WSGI server instead.
* Debug mode: off
Usage: fsksc server run [OPTIONS]
Error: Could not locate a Flask application. You did not provide the "FLASK_APP" environment variable, and a "wsgi.py" or "app.py" module was not found in the current directory.
I can fix this by defining the FLASK_APP
environment variable correctly.
Then flask run
works as expected:
$ export FLASK_APP=/Users/ewels/GitHub/flask-subcommand-issue/fsksc/server/app.py:create_fsksc_app
$ fsksc server run
* Serving Flask app "/Users/ewels/GitHub/flask-subcommand-issue/fsksc/server/app.py:create_fsksc_app"
* Environment: production
WARNING: Do not use the development server in a production environment.
Use a production WSGI server instead.
* Debug mode: off
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
flask run
also works.
But - I don't want to have to get my users to do this! I also don't want to pollute my main command group with the flask subcommands (in reality I have a lot more subcommands in the main group).
What do I need to do to make this work as I intend, without having to define FLASK_APP
and as a nested group in click?
Thank you in advance for any help!
Create a file named .flaskenv
under the root of your project, put this content into it:
FLASK_APP=fsksc.server.app:create_fsksc_app
then install python-dotenv:
$ pip install python-dotenv
Now the env var should be set automatically when you excute your run command.