7

Flask 2.0 版本发布

 2 years ago
source link: https://zhuanlan.zhihu.com/p/371659808
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Flask 2.0 版本发布

greyli.com

Flask 以及 Flask 依赖的 5 个 Pallets 项目都在今天发布了新的主版本(下面的链接指向各个项目的主版本变动日志):

​你可以使用下面的命令更新 Flask:

 pip install -U flask

如果你使用的国内 PyPI 镜像还没有同步最新版本,可以通过下面的命令临时切换到官方 PyPI 源:

 pip install -U flask -i https://pypi.org/simple/

这篇文章会介绍一些 Flask 新增的特性,完整的变动可以参考上面各个项目的变动日志。

三个核心特性

嵌套蓝本(#3923

对于一个比较大的项目,一般会使用蓝本来组织不同的模块。而如果你的项目非常大,那么嵌套蓝本就可以派上用场了。借助嵌套蓝本支持,你可以在某个蓝本之内再创建多个子蓝本,对项目进行多层模块化组织(而且支持无限嵌套,你可以嵌套很多层):

 parent = Blueprint("parent", __name__)  # 创建父蓝本
 child = Blueprint("child", __name__)  # 创建子蓝本
 parent.register_blueprint(child, url_prefix="/child")  # 把子蓝本注册到父蓝本上
 app.register_blueprint(parent, url_prefix="/parent")  # 把父蓝本注册到程序实例上

这样在生成子蓝本的 URL 时需要传入完整的端点链:

 url_for('parent.child.create')
 /parent/child/create

这个特性来源于一个 2012 年创建的 feature request issue

基本的 async/await 支持(#3412

Flask 2.0 带来了基本的异步支持,现在你可以定义异步视图(以及异步错误处理函数、异步请求钩子函数):

 import asyncio
 from flask import Flask
 ​
 app = Flask(__name__)
 ​
 @app.route('/')
 async def say_hello():
     await asyncio.sleep(1)
     return {'message': 'Hello!'}

注意要先安装额外依赖:

 pip install -U flask[async]

顺便说一句,如果你在 Windows 上使用 Python 3.8,那么会有一个来自 Python 或 asgiref 的 bug 导致出错:ValueError: set_wakeup_fd only works in main thread。可以通过下面两种方式(任选一种)处理(具体参考这个 SO 回答):

  • 升级到 Python 3.9
  • 在你的入口脚本顶部添加临时修复代码:
# top of the file
import sys, asyncio

if sys.platform == "win32" and (3, 8, 0) <= sys.version_info < (3, 9, 0)::
    asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())

不过目前只是一个基于 asgiref 的异步实现,作为异步支持的第一步,后续还会进行更多的优化和改进,更多相关信息可以参考文档

快捷路由装饰器(#3907

新增了下面的快捷路由装饰器:

  • app.get()
  • app.post()
  • app.delete()
  • app.put()
  • app.patch()

举例来说,使用 app.post() 等同于 app.route(methods=['POST'])

 from flask import Flask
 ​
 app = Flask(__name__)
 ​
 @app.post('/')
 def index():
     return {'message': 'Hello!'}

注意不要在这些快捷装饰器里传入 methods 参数。如果需要在单个视图处理多个方法的请求,使用 app.route()

我在某次 pallets 会议上提议添加这些装饰器时一开始是被拒绝的,后来 Phil Jones 创建了 #3907 经过二次讨论后才最终合并(被拒绝后我就把当时正在开发的 APIFlask 从扩展改成了继承 Flask 基类的框架,然后加了这些装饰器)。

我添加的三个特性

修复执行 flask run 找不到程序的奇怪设定(#3560

这个像 bug 又像是 feature 的设定我在《不要在 Flask 程序上层目录创建 .env 和 .flaskenv 文件》里详细说过,最终终于在两年后修复了。

支持在 .flaskenv 和 .env 文件里写中文(#3932

我在《Flask Web 开发实战》第一章介绍 .flaskenv 文件时给了一个示例,演示如何添加注释:

SOME_VAR=1
# 这是注释

但这个示例没有实际测试……加了中文其实会报错,后来有两次收到读者反馈,最终终于在三年后修复了。

为文档添加命令切换面板(#3714

这个或许算不上特性,不过在我看来是对用户非常友好的变动。除了个别不需要区分操作系统和命令行程序的命令外,我给文档里所有的命令添加了支持切换 Bash/CMD/Powershell 以及 macOS/Linux/Windows 的切换面板(面板的样式后续会有一些优化):

其他的有用特性

  • 优化了浏览器缓存控制,对 CSS、图片等静态文件做出的变动会在程序重载后立刻更新,不再需要手动清除页面缓存。
  • Werkzeug 的 multipart 解析(尤其是大文件上传处理)性能提高了 15 倍。
  • 配置对象增加 Config.from_file() 方法支持从任意文件加载器导入配置(比如 toml.loadjson.load),未来会取代 Config.from_json() 方法。
  • 在使用环境变量 FLASK_APP 指定工厂函数时支持传入关键字参数。
  • flask shell 支持 tab 和历史补全(需要安装 readline)。
  • CLI 系统优化了找不到程序时的错误处理和错误输出显示,同时修正了 Windows 上的命令行颜色输出。

破坏性变动

主要的破坏性变动(breaking change)是意外的把 send_from_directory() 函数的第二个参数名称直接由 filename 重命名为 path,将会在 2.0.1 加回来(#4019)。

另外 send_file() 函数的三个参数也进行了重命名(旧名称将在 2.1.0 移除):

  • attachment_filename -> download_name
  • cache_timeout -> max_age
  • add_etags -> etag

其他重要变化

  • 不再支持 Python 2 和 Python 3.5。
  • 所有 Pallets 项目添加 type hinting,这意味着更好的 IDE 自动补全体验。
  • 所有仓库的主分支由 master 改为 main。如果你在本地克隆了 Flask 等仓库,可以使用下面的命令来更新:
 git branch -m master main
 git fetch origin
 git branch -u origin/main main
 git remote set-head origin -a

这次更新对于整个 Pallets 项目来说是一个新的里程碑。接下来还有许多事情要做:FlaskCon 2021 正在准备中,新建立的 Flask 社区工作小组(Flask Community Work Group)正在进行 Flask 文档翻译(如果你对中文翻译感兴趣,可以订阅这个讨论)、被遗弃扩展收容计划(这是我一直想做的事情)等等。感谢支持,敬请期待!

欢迎通过下列途径关注 Pallets 项目:

相关文章:

原文链接:https://greyli.com/flask2


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK