简体   繁体   English

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

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

Use case 用例

I have a python package using a click group to have multiple command line subcommands. 我有一个使用click组的python程序包,以具有多个命令行子命令。 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. 其他子命令是软件包的主要功能- 不是 flask应用程序。 As such, I would like the flask commands to be nested under their own group. 因此,我希望flask命令嵌套在它们自己的组下。

Example

I made a minimal example to demonstrate my problem - it's on GitHub here: https://github.com/ewels/flask-subcommand-issue 我举了一个最小的例子来演示我的问题-它在GitHub上的此处: https : //github.com/ewels/flask-subcommand-issue

What works 什么有效

In the minimal example, I set up a mini flask installation that runs with the fsksc_server command. 在最小的示例中,我设置了一个微型烧瓶安装,该安装使用fsksc_server命令运行。 This is thanks to a setuptools console_scripts entry point hook in setup.py . 这要感谢setup.py的setuptools console_scripts入口点钩子。

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..) (我尚未设置任何路由,因此访问URL会抛出404,但是服务器运行正常。)

To get the flask commands in a click subcommand I have used flask add_command with the flask group. 为了在click子命令中获得flask命令,我将flask add_command与flask组一起使用。 This main command is fsksc . 这个主要命令是fsksc The flask subcommand should be shell . flask子命令应为shell The intention is to make fsksc shell run launch the development server. 目的是使fsksc shell run启动开发服务器。

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

What doesn't work 什么不起作用

When doing anything under the server subcommand, I get a warning message about a NoAppException exception: 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.

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.

Crappy workaround 变通的解决方法

I can fix this by defining the FLASK_APP environment variable correctly. 我可以通过正确定义FLASK_APP环境变量来解决此问题。 Then flask run works as expected: 然后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 also works. flask run也可以。

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). 我也不想用flask子命令来污染我的主命令组(实际上我在主组中有很多子命令)。

The question 问题

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? 我需要做什么才能实现我的FLASK_APP ,而不必定义FLASK_APP和单击中的嵌套组?

Thank you in advance for any help! 预先感谢您的任何帮助!

Create a file named .flaskenv under the root of your project, put this content into it: 在项目的根目录下创建一个名为.flaskenv的文件,并将其内容放入其中:

FLASK_APP=fsksc.server.app:create_fsksc_app

then install python-dotenv: 然后安装python-dotenv:

$ pip install python-dotenv

Now the env var should be set automatically when you excute your run command. 现在,当您执行run命令时,应该自动设置env var。

Ok, so Grey's answer put me on the right track.. 好的,所以格雷的回答使我走上了正轨。

Unfortunately, because of how flask uses the .flaskenv files, paths have to either be absolute, or relative to the current working directory of the user. 不幸的是,由于flask如何使用.flaskenv文件,因此路径必须是绝对路径或相对于用户当前工作目录的路径。 Neither of these approaches will work for other users installing the package. 这两种方法均不适用于安装该软件包的其他用户。

However, when playing with this I found that doing a simple os.environ['FLASK_APP'] works! 但是,在玩这个游戏时,我发现做一个简单的os.environ['FLASK_APP']os.environ['FLASK_APP'] It just has to be very early on in the script execution. 它只是必须在脚本执行的早期。 Then the path can be set dynamically based on the location of the installed script, and I think everything seems to work: 然后可以根据已安装脚本的位置动态设置路径,我认为一切似乎都可以正常工作:

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

I've updated the minimal example code with this here: https://github.com/ewels/flask-subcommand-issue 我在这里更新了最小的示例代码: https : //github.com/ewels/flask-subcommand-issue

Thank you for your help Grey Li ! 感谢您的帮助灰色立

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM