从Flask 0.11版本开始,官方就建议使用
flask run
命令来取代app.run()
方法运行开发服务器。尽管如此,两年多过去了,仍然有大量新发布的文章和教程在示例中使用app.run()
方法启动程序。类似的,虽然内置的命令行支持已经非常完善,但还有很多人在使用Flask-Script
。
不得不承认,在某些特殊场景下,
app.run()
更加方便,比如创建Flask命令在附加Werkzeug
提供的性能分析中间件后启动程序,这时通过app.run()
可以直接在脚本内启动程序。但是在大多数情况下,flask run
更能胜任启动开发服务器的工作。而且,在大型项目中,使用app.run()
需要你在项目根目录单独创建一个启动脚本,flask run
则没有这个要求;在单脚本程序中,使用flask run
也可以省掉脚本末尾的两行代码。
注意 :
这两种方法都只是用来启动内置(Werkzeug提供)的开发服务器,仅适用于开发用途。在生产环境下,应该使用性能更好,更加完善的开发服务器,比如Gunicorn、uWSGI等。
不同组织形式的程序的启动方式
下面我们来了解一下使用flask run
启动开发服务器时在几种方式。
- 简单的单脚本程序
如果脚本命名为app.py
或wsgi.py
,那么在包含程序脚本的目录下直接调用flask run即可:
$ flask run
Flask会自动探测找到脚本中的程序实例并启动。如果脚本命名为其他名称,比如hello.py
,那么需要将脚本名写入环境变量FLASK_APP
,然后再调用flask run
命令:
$ export FLASK_APP=hello
$ flask run
提示 在Windows系统下,你需要使用set命令来设置环境变量,
比如
> set FLASK_APP=hello
后面的命令亦同。
①使用包组织的程序
②这种情况下,可以将包含程序实例的对应模块的路径写入FLASK_APP:
$ export FLASK_APP=my_pkg.app
$ flask run
通常情况下,我们会在包内的__init__.py
文件中创建程序实例,所以这时可以直接将包名称写入FLASK_APP
:
$ export FLASK_APP=my_pkg
$ flask run
- ③使用工厂函数创建程序实例的程序
因为Flask会自动探测程序实例,所以使用工厂函数创建程序实例时不需要进行额外设置。具体来说,Flask会在FLASK_APP
变量存储的对应模块/包构造文件中寻找名为create_app
或make_app
的函数,并调用这个函数来创建一个程序实例。
为了让你的程序能够被探测到,工厂函数的名称需要命名为create_app
或make_app
,而且要确保工厂函数接受默认值参数。这时启动开发服务器的方式仍然不变:
$ export FLASK_APP=my_pkg
$ flask run
如果你的工厂函数接受的参数不是默认参数,或者你想详细定义调用工厂函数的方式,那么也可以通过FLASK_APP
环境变量来定义:
$ export FLASK_APP="my_pkg:create_app('development')"
$ flask run
提示Flask的FLASK_APP
还接受其他形式的输入值,你可以参考文末给出的文档相关部分链接了解完整内容。
如何避免重复设置FLASK_APP环境变量?
在上面的几种方式中,除了包含程序实例的程序脚本命名为app.py
或wsgi.py
的情况外,都需要设置FLASK_APP
环境变量。有没有办法避免重启电脑或是新打开命令行会话时重复输入FLASK_APP
呢?当然。Flask提供了对一个常用的Python虚拟环境管理工具python-dotenv
的支持,我们需要先安装它:
$ pip install python-dotenv
当python-dotenv
安装后,执行flask run
命令会首先将项目根目录下的.env
和.flaskenv
文件中的环境变量写入。所以,你可以将FLASK_APP
写在这两个文件中。按照约定,.env
存储包含敏感数据的环境变量,这个文件需要加入到.gitignore
中以避免提交到Git仓库中;而.flaskenv
时Flask
特别支持的文件,这个文件则用来存储和Flask相关的环境变量,比如FLASK_ENV
、FLASK_DEBUG
等,所以我们可以把FLASK_APP
写到这个文件中:
FLASK_APP=my_pkg
现在,我们可以仅通过一个命令来启动开发服务器:
$ flask run
使用flask run时如何开启调试模式?
在使用app.run()
方法时,我们会通过将debug
参数设为True
来开启调试模式。而当使用flask run
时,则需要通过FLASK_ENV
环境变量来设置调试模式。默认情况下,FLASK_ENV
的值为production
,在开发时我们可以将其设为development
来开启调试模式。
同样的,为了避免重复写入这个环境变量,我们也将其写到.flaskenv
中:
FLASK_ENV=development
提示 目前已不推荐使用FLASK_DEBUG
来开启调试模式,当FLASK_ENV
的值为development
时调试模式会自动开启。
使用flask run时如何自定义主机和端口
在通过flask run
启动开发服务器时,你可以通过命令行选项来自定义监听的主机和端口,示例如下:
$ flask run --port 5001
下面的示例同时指定了端口和主机:
$ flask run --host 0.0.0.0 --port 5001
另外,Flask还支持通过环境变量来定义命令选项,支持的环境变量名称模式为“FLASK_命令_选项
”。比如,如果你想设置端口,那么可以定义FLASK_RUN_PORT
环境变量,作用和传入--port
选项相同。
启动包含程序上下文的Python Shell
你可以通过flask shell
命令来启动一个激活了程序上下文的Python Shell
,而不是使用python
命令:
$ flask shell
app.run() 的未来
从0.11版本到现在的1.0.2版本,app.run()始终处于不建议使用状态,而且Flask的命令行系统、flask run命令的程序探测都在逐渐完善,我觉得未来也许会正式”deprecate“这个app.run()方法。不过,因为某些特殊用途仍然需要使用app.run(),未来的变化还不好说。而且,Miguel Grinberg提交了这个PR让app.run()间接调用flask run,如果这个PR被合并,也许app.run()将会重回正轨。