# Version 21.9

# 介绍(Introduction)

21.9 版本是 21 版本周期中的第三个版本。21 版本将会在 12 月发布长期支持版本。

# 更新内容(What to know)

更多细节详见发布说明 (opens new window)。以下是值得注意的新功能或突破性变化,以及更新内容...

# 移除配置项:WEBSOCKET_READ_LIMITWEBSOCKET_WRITE_LIMITWEBSOCKET_MAX_QUEUE

随着 websocket 的完全重构,上述配置项将被移除。目前还没有计划安排替代选项。

# 弃用 FALLBACK_ERROR_FORMAT 配置项的默认值

当没有添加异常处理程序时,Sanic 使用 html 作为默认的格式类型。这点已被废弃了,从 v22.3 开始将改为 text 。虽然它的值已经变成了 auto ,但在 v21.12LTS 之前,它仍将继续使用 HTML 作为默认值。

# ErrorHandler.lookup 函数签名改动(ErrorHandler.lookup signature deprecation)

现在, ErrorHandler.lookup 方法 必须要求 传入 2 个参数:

def lookup(self, exception, route_name: Optional[str]):

这将意味着不满足这个签名的异常处理程序将会注册失败。

# 未来移除项备忘录(Reminder of upcoming removals)

作为备忘,下述项已经被弃用,并且会将在 21.12LTS 版本中被移除

  • CompositionView
  • load_env (使用 env_prefix 代替)
  • Sanic 对象 (应用实例, 蓝图和路由) 必须只能是包含数字和字母的组合: ^[a-zA-Z] [a-zA-Z0-9_\-]*$
  • 任意分配对象到应用程序和蓝图实例(使用 ctx 代替;移除随意分配已经从 21.9 移到 21.12。)

# websockets 重构(Overhaul of websockets)

在处理 websocket 上,有一些巨大的改动。 多谢了 @aaugustin (opens new window) 现在 websockets (opens new window) 已经有了全新的实现,这也允许 Sanic 自己 websocket 链接。

因此,Sanic 将修改最低依赖版本至 websockets>=10.0

除了 websocket 处理函数在异常捕获时的一些非正常情况被修复外,这些变动应该对于开发者来说没有太大影响。举例来说,您现在应该可以在断开连接时正常捕获到 CancelledError 异常。

@app.websocket("/")
async def handler(request, ws):
    try:
        while True:
            await asyncio.sleep(0.25)
    except asyncio.CancelledError:
        print("User closed connection")

# 内置信号(Built-in signals)

21.3 版本中介绍了 信号。现在,Sanic 原生支持触发信号事件。这意味着开发者将可以在完整的请求/响应生命周期中注入自己的钩子函数。

在这之前,如果您想注入一些逻辑,您只能使用中间件。把集成信号看作是 超级中间件

下列是会触发的事件列表:

  • http.lifecycle.begin
  • http.lifecycle.complete
  • http.lifecycle.exception
  • http.lifecycle.handle
  • http.lifecycle.read_body
  • http.lifecycle.read_head
  • http.lifecycle.request
  • http.lifecycle.response
  • http.lifecycle.send
  • http.middleware.after
  • http.middleware.before
  • http.routing.after
  • http.routing.before
  • server.init.after
  • server.init.before
  • server.shutdown.after
  • server.shutdown.before

备注

server 信号和四个主服务监听器是一样。事实上,这些监听器本身就是使用信号来实现的。

# 更加智能的格式化异常:auto(Smarter auto exception formatting)

Sanic 现在会尝试根据端点和客户端去返回一个合适的异常信息格式。比如,如果您的端点总是返回 sanic.response.json 对象,那么任何异常将会被自动得格式化成 JSON。texthtml 响应同理。

此外,您可以在定义路由的时候 精确地 控制异常格式化的方式:

@app.route("/", error_format="json")
async def handler(request):
    pass

# 蓝图拷贝(Blueprint copying)

蓝图可以被复制到新的实例中。这将会复制所有在该蓝图上注册的控制程序,如路由、中间件等。

v1 = Blueprint("Version1", version=1)
@v1.route("/something")
def something(request):
    pass
v2 = v1.copy("Version2", version=2)
app.blueprint(v1)
app.blueprint(v2)
/v1/something
/v2/something

# 蓝图组便捷方法(Blueprint group convenience methods)

蓝图组现在拥有与普通蓝图拥有相同的方法,加上复制功能,蓝图现在可以被十分灵活得组合。

# Accept 头解析(Accept header parsing)

Sanic Request 对象可以解析 Accept 头信息,并会将头信息组织一个有序列表,该头信息代表着客户端倾向的数据类型 (content-type)。您可以通过以下属性非常简单的获取该值:

print(request.accept)
# ["*/*"]

它还能够处理通配符。举个例子,假设有如下请求:

Accept: */*

那么,下述代码执行的结果为 True

"text/plain" in request.accept

# 默认异常信息(Default exception messages)

任何继承自 SanicException 的异常现在可以定义一个默认的信息。这使得异常的重用更加方便,也使得异常更可维护,同时让您远离 一次且仅一次 (DRY) 问题。

class TeaError(SanicException):
    message = "Tempest in a teapot"
raise TeaError

# 方便的类型注释(Type annotation conveniences)

现在,您可以使用 Python 的类型注释来控制路径参数。

之前,您可能需要这么定义路径参数:

@app.route("/<one:int>/<two:float>/<three:uuid>")
def handler(request: Request, one: int, two: float, three: UUID):
    ...

现在,您有更加方便的写法:

@app.route("/<one>/<two>/<three>")
def handler(request: Request, one: int, two: float, three: UUID):
    ...

上述两个例子拥有同样的效果。

# 明确静态资源类型(Explicit static resource type)

您现在可以明确 static 的路由处理的资源类型,告知该路由应该把资源当作文件还是目录来处理:

static("/", "/path/to/some/file", resource_type="file"))

# 新闻(News)

# 发布 sanic-ext 并且弃用 sanic-openapi(Release of sanic-ext and deprecation of sanic-openapi)

Sanic 的其中一个核心原则就是,它应该是一个工具,而不是一个独裁者。正如我们在首页中提到的那样:

按照您的意愿进行自由创建,不会对您造成任何约束

这意味着很多通用的功能(特别是 Web Api 开发者经常使用的那些)将不会被集成到 sanic 主仓库中。这样做的好处是不限制开发者的自由创作,不会产生任何约束。

但是,有时您不想去反复编写那些相同的东西。到目前为止,Sanic 依赖社区提供强大支持来填补插件的空白。

早些时候,有一个官方的 sanic-openapi 包,它提供了基于您的应用来生成 OpenAPI 文档的功能。相比于 Sanic 的主项目,该项目已经多年来都没有给予过足够的关注。

从 v21.9 版本开始,SCO 废弃了 sanic-openapi 包并且将其转为维护模式。这意味着它将只会进行必要的更新,但它将不会获得任何新的增强功能。

一个名为 sanic-ext 的新项目取代它的位置。这个包不仅提供了生成 OAS3 文档的能力,而且为 API 开发者进一步铺平了道路。例如,再您使用时,它将设置 CORS,并在需要时自动启用 HEADOPTIONS 响应。它还能够使用标准库 Dataclasses 或Pydantic 模型来进行数据简要。

它提供的功能包括:

  • CORS 保护
  • 请求参数验证
  • 支持自动生成 OAS3,并且能使用 Redoc 或者 Swagger UI 自动生成文档
  • 自动 HEAD, OPTIONS TRACE 响应
  • 依赖注入
  • 序列化响应

该项目仍然处理 alpha 测试阶段,随时都会发生改动。虽然它被指望能够胜任生产环境,但随着功能的增加,可能会改变一些 API。

查看插件文档来获取更多细节。

# 鸣谢(Thank you)

感谢每一位参与本次发布的人:👏

@aaugustin (opens new window) @ahopkins (opens new window) @ashleysommer (opens new window) @cansarigol3megawatt (opens new window) @ChihweiLHBird (opens new window) @gluhar2006 (opens new window) @komar007 (opens new window) @ombe1229 (opens new window) @prryplatypus (opens new window) @SaidBySolo (opens new window) @Tronic (opens new window) @vltr (opens new window)

并且,特别感谢 @miss85246 (opens new window)@ZinkLu (opens new window),他们在同步翻译最新中文文档上付出了巨大精力。


如果您喜欢本项目,请考虑参与建设本项目。我们欢迎您提交代码,也欢迎您以任何其他方式来参与本项目的建设。比如撰写文档,分享使用心得,参与社区讨论,当然,如果经济允许,您也可以考虑经济资助 (opens new window)

MIT Licensed
Copyright © 2018-present Sanic Community Organization

~ Made with ❤️ and ☕️ ~