如何在不手动设置FLASK_APP的情况下通过烧瓶运行或自定义命令运行Flask应用

时间:2019-03-20 21:57:35

标签: python flask python-click

用例

我有一个使用click组的python软件包,具有多个命令行子命令。 除此之外,我还希望有一个小的烧瓶应用程序。

其他子命令是软件包的主要功能-不是flask应用程序。 因此,我希望flask命令嵌套在它们自己的组下。

示例

我举了一个最小的例子来演示我的问题-它在GitHub上的https://github.com/ewels/flask-subcommand-issue

什么有效

在最小的示例中,我设置了一个迷你烧瓶安装,该安装使用fsksc_server命令运行。 这要归功于console_scripts中的setuptools setup.py入口点挂钩。

该命令可以完美运行,完全符合您的预期:

$ 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)

(我没有设置任何路由,因此访问URL会抛出404,但是服务器运行正常。)

要在click子命令中获得flask命令,我已将flask add_command与flask组一起使用。 这个主要命令是fsksc。 flask子命令应为shell。 目的是使fsksc shell run启动开发服务器。

命令正确显示,因此这部分似乎可以正常工作

$ fsksc --help

Usage: fsksc [OPTIONS] COMMAND [ARGS]...

Options:
  --help  Show this message and exit.

Commands:
  cmd1
  cmd2
  server  Run the fsksc server flask app

什么不起作用

server子命令下执行任何操作时,我收到有关NoAppException异常的警告消息:

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

尝试运行服务器会出现类似错误:

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

胡扯的解决方法

我可以通过正确定义FLASK_APP环境变量来解决此问题。 然后flask run会按预期工作:

$ 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也可以。

但是-我不想让我的用户这样做! 我也不想用flask子命令污染我的主命令组 (实际上,主组中有更多子命令。)

问题

我该怎么做才能按预期进行此工作,而不必定义FLASK_APP并单击时将其作为嵌套组?

在此先感谢您的帮助!

2 个答案:

答案 0 :(得分:1)

在项目的根目录下创建一个名为.flaskenv的文件,并将其内容放入其中:

FLASK_APP=fsksc.server.app:create_fsksc_app

然后安装python-dotenv:

$ pip install python-dotenv

现在,执行运行命令时应自动设置环境变量。

答案 1 :(得分:1)

好吧,Grey's answer让我走上了正轨。

不幸的是,由于flask如何使用.flaskenv文件,因此路径必须是绝对路径或相对于用户当前工作目录的路径。这两种方法均不适用于安装该软件包的其他用户。

但是,当我玩这个游戏时,我发现做一个简单的os.environ['FLASK_APP']是可行的!它只是必须在脚本执行的早期。然后可以根据已安装脚本的位置动态设置路径,我认为一切似乎都可以正常工作

flaskenv_app_path = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'fsksc', 'server', 'app.py')
flaskenv_app_func = '{}:create_fsksc_app'.format(flaskenv_app_path)
os.environ['FLASK_APP'] = flaskenv_app_func

我在此处更新了最小示例代码:https://github.com/ewels/flask-subcommand-issue

感谢您的帮助Grey Li