【问题标题】:How to run Flask app by flask run or custom command without set FLASK_APP manually如何在不手动设置 FLASK_APP 的情况下通过烧瓶运行或自定义命令运行 Flask 应用程序
【发布时间】:2019-08-11 17:43:36
【问题描述】:

用例

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

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

示例

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

什么有效

在最小示例中,我设置了一个使用fsksc_server 命令运行的迷你烧瓶安装。 这要归功于 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,但服务器运行良好..)

为了在 click 子命令中获取烧瓶命令,我在烧瓶组中使用了烧瓶 add_command。 这个主要命令是fsksc。烧瓶子命令应该是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_APP 并作为 click 中的嵌套组?

提前感谢您的帮助!

【问题讨论】:

    标签: python flask python-click


    【解决方案1】:

    在你的项目根目录下创建一个名为.flaskenv的文件,把这个内容放进去:

    FLASK_APP=fsksc.server.app:create_fsksc_app
    

    然后安装python-dotenv:

    $ pip install python-dotenv
    

    现在 env var 应该会在您执行运行命令时自动设置。

    【讨论】:

    • 太棒了,谢谢!请注意,我必须另外指定一个 flask.cli.load_dotenv() 命令才能使其正常工作,但这有一个额外的好处,即我可以使用烧瓶代码在子目录中整理新的 .flaskenv 文件。我还为FLASK_APP 使用了相对路径,以便它适用于所有用户。对自己有点恼火,我自己没有弄清楚这一点——我看过flask docs 关于python-dotenv,但没有把 2+2 放在一起来意识到这可以解决我的问题。谢谢!
    • 我在 GitHub 上更新了最小解决方案以帮助未来的读者:github.com/ewels/flask-subcommand-issue
    • 该死,我说得太早了。当您从其他工作目录启动时,相对路径不起作用。任何想法如何使FLASK_APP 为任何用户工作?
    • 不客气!也许您可以只传递模块导入路径,检查更新的答案。
    • 是的,使用此设置,您必须从项目根目录执行命令。您的解决方案看起来很适合您的需求,只需投票 :)
    【解决方案2】:

    好的,所以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

    【讨论】:

      猜你喜欢
      • 2020-09-10
      • 1970-01-01
      • 2015-07-05
      • 1970-01-01
      • 2022-01-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-12-13
      相关资源
      最近更新 更多