新版本的Flask中如何启动开发服务器和开启调试模式 - 知乎
从Flask 0.11版本开始,官方就建议使用flask run
命令来取代app.run()
方法运行开发服务器。尽管如此,两年多过去了,仍然有大量新发布的文章和教程在示例中使用app.run()
方法启动程序。类似的,虽然内置的命令行支持已经非常完善,但还有很多人在使用Flask-Script。
Added flask and theflask.cli
module to start the local debug server through the click CLI system. This is recommended over the oldflask.run()
method as it works faster and more reliable due to a different design and also replacesFlask-Script
.
Flask Changelog 0.11
不得不承认,在某些特殊场景下,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
等命令时,Flask 会自动将项目根目录下的.env
和.flaskenv
文件中的环境变量写入当前系统环境(如果你使用 Flask 1.0 以下版本,则需要手动设置)。所以,你可以将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()
将会重回正轨。
就目前来说,flask run
要远比app.run()
更加方便、好用、简洁、直观,准备好了吗?穿上新衣服吧。
相关链接
- Flask文档“程序发现”部分:Command Line Interface
- Flask Changelog:Flask Changelog - Flask 1.0.2 documentation