Flask编程入门(四)Flask启动参数

上一节中讲到Flask有两种方式,即在app.py中使用代码运行和在终端中使用flask run命令运行,本节中我们将着重介绍在这两种启动方式中分别如何通过传入的参数指定Flask服务器的配置。

一、在app.py中使用代码运行

追踪启动函数的代码可以发现,该函数具有如下一些参数:

首先我们了解一下除了可选参数options之外的其他基本参数:

  • host:用于指定Flask Web应用程序所绑定的网络接口,其值应为需绑定的接口的IP地址,可以是IPv4地址也可以是IPv6地址。在开发环境中可以填写为本机的局域网IP地址,而在生产环境中则最好只绑定Loopback环回地址(即IPv4地址127.0.0.1或IPv6地址[::1]),不要将应用程序直接暴露在互联网上,而是使用Nginx或Apache等专业Web服务器进行反向代理,以增强性能和安全性。默认值为127.0.0.1。
  • port:用于指定Flask Web应用程序所绑定的端口,协议为HTTP或HTTPS(基于TCP),两种协议只能同时开启一种,若调用两次app.run()分别开启两种协议则会出错。默认值为5000。
  • debug:用于指定是否开启调试模式,若设置为True,则启动后会出现一个9位的Debugger PIN。调试模式的作用主要有两个:首先,Flask会开启watchdog监控项目文件夹中的代码是否被修改,如果修改代码并保存,则会自动重新加载项目而无需手动重启;其次,如果代码执行中出现异常,可以在浏览器中显示异常的Traceback信息(和终端中显示的信息相同)。默认值为False。
  • load_dotenv:是否从项目目录下的.env或.flaskenv文件中加载环境变量,例如上面的三个启动参数也可以通过该方式来指定,如果没有找到则会使用代码中指定的值或默认参数。默认值为True。

注意:(1)host和port共同构成一个二元组,作为参数指定Flask Web应用程序所绑定的Socket,这个二元组在当前机器上必须是唯一的,即其他应用程序不能占用host接口上的port端口,否则会出错;

(2)如果在网页上需要访问调试器并执行代码则需要输入Debugger PIN,虽然有了这一层安全认证机制,但是根据Debugger PIN的生成算法,同一个项目在同一个虚拟环境中生成的数值是完全相同的,因此不要将调试模式的应用程序直接暴露在互联网上,否则容易被暴力破解。

例如下列代码中有一个很明显的错误,访问页面后会产生如下的异常:

@app.route('/')
def hello():
    test = int("3z")
    return 'Hello, Flask!'

此时将鼠标移至Traceback跟踪的代码执行路径中任意一行代码最右侧,即可看到一个终端的图标,点击之后会提示终端已锁定,输入Debugger PIN验证后即可出现交互式终端并执行任意的Python代码。

继续追踪启动函数的代码可以发现,可选参数options传入了run_simple函数中,且参数提示中显示options中可使用的参数可以参数run_simple函数的参数,因此我们继续追踪run_simple函数。

可以看到run_simple函数具有很多参数,其中只有一部分是我们需要关心的:

  • threaded:用于指定是否使用多线程模式,不能和processes参数同时指定。由于目前的Python版本在默认情况下受全局解释锁GIL的限制,一个进程中只有一个线程能拿到GIL锁,因此在单进程模式下,暂时还不能通过多线程实现真正的并行请求处理。新版本的Python关闭GIL应当能够并行处理请求了。对于run_simple函数来说默认值为False,即使用单线程模式。但是Flask框架的服务器在代码中指定了threaded为True,即Flask Web应用程序默认使用多线程模式
  • processes:用于指定是否使用多线程模式,设置为1时为单进程模式,大于1时为多进程模式。由于Flask框架的服务器不支持同时使用多线程和多进程模式,默认使用多线程模式,如果需要设置多进程模式,首先需要关闭多线程模式,即指定threaded为False。多进程模式依赖于fork系统调用,因此不适用于Windows平台,仅适用于Linux和BSD等实现了Unix标准中的fork系统调用的系统。
  • ssl_context:用于指定开启HTTPS协议所需的上下文信息,即SSL证书和私钥文件的路径,是一个二元组,其格式为('SSL证书文件的路径', 'SSL证书私钥的路径')。如果没有指定默认开启HTTP协议,指定证书上下文后只开启HTTPS协议。如果需要开启HTTPS协议或同时开启二者,由于性能问题,建议在生产环境中使用Nginx或Apache等专业Web服务器处理HTTPS请求
  • extra_files:指定除项目文件夹中的文件外watchdog需要监控修改的文件的路径,如果配置文件或资源文件在其他路径下可能会用到,需要提供一个可迭代且包含内容全为字符串的对象,如列表List。当这些文件修改并保存后,如果开启了调试模式,也会触发自动重新加载项目。
  • exclude-patterns:指定项目文件夹中watchdog无需监控修改的文件名的特征,需要提供一个可迭代且包含内容全为字符串的对象,如列表List。当满足特征的文件修改并保存后,即时开启了调试模式且在项目文件夹下,也不会触发自动重新加载项目。

附:(1)指定需额外监控修改的文件路径:

if __name__ == '__main__':
    ssl_keys = ('ssl.crt', 'ssl.key')
    app.run(debug=True, extra_files=[r"C:\Users\brj\Downloads\6.txt"])

可以看到,修改该文件后,即使该文件不在项目文件夹下,也会触发自动重新加载项目:

(2)指定无需监控修改的文件名特征:

例如排除所有.cfg文件的监控,其文件名特征字符串是”*.cfg“;

排除所有名为”tests“的文件夹和其中的文件的监控,其文件名特征字符串是”*/tests/*“;

因此最终的文件名特征字符串列表是["*.cfg", "*/tests/*"],具体代码如下:

if __name__ == '__main__':
    ssl_keys = ('ssl.crt', 'ssl.key')
    app.run(debug=True, exclude_patterns=["*.cfg", "*/tests/*"])

(3)直接开启HTTPS的方法:

if __name__ == '__main__':
    ssl_keys = ('ssl.crt', 'ssl.key')
    app.run(debug=True, ssl_context=ssl_keys)

二、在终端中使用flask run命令运行

在终端中输入flask run --help即可得到flask run命令接受的各种参数列表,启动参数有对应一个单横线和字母(简写)以及两个单横线和完整参数名称(全拼)两种指定方式,具体如下所示:

  • --debug:相当于上一种方法的debug参数设置为True的作用,需手动指定。
  • --no-debug:相当于上一种方法的debug参数设置为False的作用,是默认值。
  • -h/--host:同上一种方法的host参数的作用。
  • -p/--port:同上一种方法的port参数的作用。
  • --cert:同上一种方法的ssl_context中的”SSL证书文件的路径“的作用。
  • --key:同上一种方法的ssl_context中的”SSL证书私钥的路径“的作用。
  • --reload:检测到项目代码文件修改后自动重载服务器,指定debug参数时为默认值。
  • --no-reload:检测到项目代码文件修改后不要自动重载服务器,未指定debug参数时为默认值。
  • --debugger:开启调试器,指定debug参数时为默认值。
  • --no-debugger:不要开启调试器,未指定debug参数时为默认值。
  • --with-threads:开启多线程模式,是默认值。
  • --without-threads:关闭多线程模式,即单线程模式。
  • --extra-files:同上一种方法的extra_files参数的作用,区别是需要提供字符串参数,如果有多个文件路径则需要使用英文分号”;“分隔。
  • --exclude-patterns:同上一种方法的exclude-patterns参数的作用,区别是需要提供字符串参数,如果有多个文件名特征则需要使用英文分号”;“分隔。
  • --help:输出帮助信息,即上述启动参数的指定方式及其含义。

由于标准的Flask命令行没有提供processes参数,因此在终端中使用flask run命令运行Flask Web应用程序时无法使用多进程模式,因为通常生产环境中WSGI服务器有自己的多进程服务器启动方式。

一个完整的在终端中使用flask run命令运行Flask Web应用程序的命令如下所示:

flask -A app run --debug -h 127.0.0.1 -p 5000 --cert "ssl.crt" --key "ssl.key" --reload --debugger --with-threads --extra-files "C:\Users\brj\Downloads\6.txt;C:\Users\brj\Downloads\7.txt" --exclude-patterns "*.cfg;*/tests/*"

如果要执行的Flask Web应用程序文件名是app.py,则可以省略”-A app“或”-app app“这个参数。

注意:如果传入的参数是字符串且其中含有空格,则整个字符串都必须使用引号包含起来,否则参数会在空格处被截断导致出现错误,因此建议字符串参数都使用引号包含起来。

执行的结果如下,和上一种方法实现的效果是一致的:

这两种简单的启动方法主要是用于调试阶段,之后会介绍在生产环境中如何用WSGI服务器来实际部署,届时还需要引入一些新的启动方法和参数。

相关推荐