如何通过 flask 运行 或不手动设置 FLASK_APP 的自定义命令 运行 Flask 应用程序

How to run Flask app by flask run or custom command without set FLASK_APP manually

用例

我有一个 python 包使用 click 组来拥有多个命令行子命令。 除此之外,我还想要一个小烧瓶应用。

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

例子

我做了一个最小的例子来说明我的问题 - 它在GitHub这里:https://github.com/ewels/flask-subcommand-issue

什么有效

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

中的 setuptools console_scripts 入口点挂钩

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

$ 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,但是服务器是 运行ning fine..)

为了在单击子命令中获取 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 并作为点击中的嵌套组?

提前感谢您的帮助!

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

FLASK_APP=fsksc.server.app:create_fsksc_app

然后安装python-dotenv:

$ pip install python-dotenv

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

好的,所以 让我走上正轨..

不幸的是,由于 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