# Version 21.9
- 介绍(Introduction)
- 更新内容(What to know)
- 移除配置项:WEBSOCKET_READ_LIMIT,WEBSOCKET_WRITE_LIMIT 和 WEBSOCKET_MAX_QUEUE
- 弃用 FALLBACK_ERROR_FORMAT 配置项的默认值
- ErrorHandler.lookup 函数签名改动(ErrorHandler.lookup signature deprecation)
- 未来移除项备忘录(Reminder of upcoming removals)
- websockets 重构(Overhaul of websockets)
- 内置信号(Built-in signals)
- 更加智能的格式化异常:auto(Smarter auto exception formatting)
- 蓝图拷贝(Blueprint copying)
- 蓝图组便捷方法(Blueprint group convenience methods)
- Accept 头解析(Accept header parsing)
- 默认异常信息(Default exception messages)
- 方便的类型注释(Type annotation conveniences)
- 明确静态资源类型(Explicit static resource type)
- 新闻(News)
- 鸣谢(Thank you)
# 介绍(Introduction)
21.9 版本是 21 版本周期中的第三个版本。21 版本将会在 12 月发布长期支持版本。
# 更新内容(What to know)
更多细节详见发布说明 (opens new window)。以下是值得注意的新功能或突破性变化,以及更新内容...
# 移除配置项:WEBSOCKET_READ_LIMIT
,WEBSOCKET_WRITE_LIMIT
和 WEBSOCKET_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。text
和 html
响应同理。
此外,您可以在定义路由的时候 精确地 控制异常格式化的方式:
@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,并在需要时自动启用 HEAD
和 OPTIONS
响应。它还能够使用标准库 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)。