# Version 21.6
- 介绍(Introduction)
- 更新内容(What to know)
- 弃用 StreamingHTTPResponse (Deprecation of StreamingHTTPResponse)
- 弃用 CompositionView(Deprecation of CompositionView)
- 弃用路径参数类型: string 和 number (Deprecation of path parameter types: string and number)
- 升级至0.7版本的路由(Version 0.7 router upgrades)
- 使用 eof() 来结束流式传输(Inline streaming with eof())
- 新的路径参数类型 slug (New path parameter type: slug)
- 更加严格的应用蓝图名称,弃用随意的命名方式(Stricter application and blueprint names, and deprecation)
- Route 对象的 route.uri 新属性 (A new access on Route object: route.uri)
- Request 对象包含ip信息的新属性(A new accessor on Request object impacting IPs)
- 可选的 Config 和 Sanic.ctx 对象 (Alternate Config and Sanic.ctx objects)
- Sanic 命令行工具改进(Sanic CLI improvements)
- 版本前缀(Version prefix)
- 信号事件的自动注册(Signal event auto-registration)
- 可重复利用和可嵌套的 Blueprint 和 BlueprintGroup (Infinitely reusable and nestable Blueprint and BlueprintGroup)
- HTTP 方法作为 Enum (HTTP methods as Enum)
- 拓展 HTTPMethodView (Expansion of HTTPMethodView)
- 新闻(News)
- 鸣谢(Thank you)
# 介绍(Introduction)
这是 21 版本发布周期内的第二次发布。我们将在 12 月份发布长期支持办,在此之前,我们还会在 9 月还会进行一次发布。值得注意的是,在 21.3 版本中,路由已经被作为依赖被移动到了单独的包中: sanic-routing
(opens new window)。这一变化可能会暂时保留。从这个版本开始,路由最低要求的版本是0.7.0。
# 更新内容(What to know)
更多细节详见发布说明 (opens new window)。以下是值得注意的新功能或突破性变化,以及更新内容...
# 弃用 StreamingHTTPResponse
(Deprecation of StreamingHTTPResponse
)
StreamingHTTPResponse
已经被弃用,并将在 21.12 版本中删除。这将影响 sanic.response.stream
和 sanic.response.file_stream
方法,它们都依赖 StreamingHTTPResponse
对象。
尽管确切的迁移路线还没有确认,但是 sanic.response.stream
和 sanic.response.file_stream
将继续以某种便捷操作的形式继续存在于 v21.12 中。我们希望经历一个夏天的讨论,在 9 月的发布前确定更多细节。
# 弃用 CompositionView
(Deprecation of CompositionView
)
CompositionView
已经被弃用,并且将在 21.12 版本中删除。
# 弃用路径参数类型: string
和 number
(Deprecation of path parameter types: string
and number
)
今后,您应该使用 str
和 float
作为路径参数类型来替代原先的 string
和 number
。
@app.get("/<foo:str>/<bar:float>")
async def handler(request, foo: str, bar: float):
...
现有的 string
和 number
类型将作为新类型的别名,但将在v21.12中被删除。
# 升级至0.7版本的路由(Version 0.7 router upgrades)
在0.7版本中,修复了一些列 bug,并且相比 0.6 版本,新版本能优雅地处理更多的边缘情况。如果您遇到任何不支持的路由模式,请在这里反馈 (opens new window)。您可以在 sanic-routing
发布说明 (opens new window)中看到一些问题的解决。
# 使用 eof()
来结束流式传输(Inline streaming with eof()
)
我们在 21.3 中对处理流式传输进行了重大变更 (opens new window),并且提供了新的串流方式。为了提供进一步的便利,我们在 21.6 中加入了一个新的 response.eof()
方法来结串流。一旦所有的数据被推送到客户端,就该调用该方法。
@app.route("/")
async def test(request):
response = await request.respond(content_type="text/csv")
await response.send("foo,")
await response.send("bar")
await response.eof()
return response
# 新的路径参数类型 slug
(New path parameter type: slug
)
您现在可以使用 slug
类型来指定一段动态的路径并进行适当的匹配。
@app.get("/articles/<article_slug:slug>")
async def article(request, article_slug: str):
...
slug
必须由小写字母或数字组成。它可以包含多个连字符(-
),但它不能放在开头。
this-is-a-slug
with-123-is-also-a-slug
111-at-start-is-a-slug
NOT-a-slug
-NOT-a-slug
# 更加严格的应用蓝图名称,弃用随意的命名方式(Stricter application and blueprint names, and deprecation)
您的应用和蓝图实例必须符合一套更严格命名的要求。
- 只能由字母数字字符组成
- 可以包含一个连字符(
-
)或下划线(_
) - 必须以一个字母开头(大写或小写)
这样的命名规则类似于 Python 的变量命名规则,但增加了允许连字符(-
)。
较随意的命名标准已被废除。从 21.12 开始,不符合标准的名称将会导致一个运行时的错误。
# Route
对象的 route.uri
新属性 (A new access on Route
object: route.uri
)
v21.3 中的 Route
对象不再有 uri
属性。取而代之的是 route.path
。然而,由于 sanic-routing
的工作方式,path
属性 不能 再以斜杠 /
开头。所以现在设置以斜杠开头的 route.uri
属性来作为补充。
route.uri == f"/{route.path}"
# Request
对象包含ip信息的新属性(A new accessor on Request
object impacting IPs)
Request 对象上有一个 request.ip
属性能很方便地获取请求的 IP 信息。这个属性值来自另一个包含了更多 HTTP 连接细节的底层对象:request.conn_info
。
目前的版本为 conn_info
对象增加了一个新的 client_ip
属性。对于 IPv4 ,您不会注意到有什么不同。然而,对于 IPv6 的应用,新的属性将提供一个“无包装”的地址版本。请看下面的例子:
@app.get("/")
async def handler(request):
return json(
{
"request.ip": request.ip,
"request.conn_info.client": request.conn_info.client,
"request.conn_info.client_ip": request.conn_info.client_ip,
}
)
app.run(sock=my_ipv6_sock)
$ curl http://\[::1\]:8000
{
"request.ip": "::1",
"request.conn_info.client": "[::1]",
"request.conn_info.client_ip": "::1"
}
# 可选的 Config
和 Sanic.ctx
对象 (Alternate Config
and Sanic.ctx
objects)
您现在可以为 Sanic 应用传入自定义的配置和上下文对象。自定义的配置应该是 sanic.config.Config
的子类。上下文则可以被设置为任何对象,没有限制。
class CustomConfig(Config):
...
config = CustomConfig()
app = Sanic("custom", config=config)
assert isinstance(app.config, CustomConfig)
和:
class CustomContext:
...
ctx = CustomContext()
app = Sanic("custom", ctx=ctx)
assert isinstance(app.ctx, CustomContext)
# Sanic 命令行工具改进(Sanic CLI improvements)
- 现有功能新标志:
--auto-reload
- 现有参数的的新缩写标志
- 新功能:
--factory
- 新功能:
--simple
- 新功能:
--reload-dir
# 工厂应用(Factory applications)
对于遵循工厂模式(一个返回 sanic.Sanic
实例的函数)的应用程序,您可以在 Sanic 命令行工具中添加 --factory
标志来启动它。
from sanic import Blueprint, Sanic, text
bp = Blueprint(__file__)
@bp.get("/")
async def handler(request):
return text("😎")
def create_app() -> Sanic:
app = Sanic(__file__)
app.blueprint(bp)
return app
您可以使用如下命令来启动:
$ sanic path.to:create_app --factory
# 简易服务器(Sanic Simple Server)
Sanic 命令行工具现在添加了简易模式的命令,它将启动一个 Sanic 服务并代理指定目录下的静态文件,同时也会在第一级目录中自动寻找 index.html
文件。
$ sanic ./path/to/dir --simple
注意
该功能目前仍处于早期测试阶段。可能会在今后的版本中更改。
# 指定额外的重启监听目录(Additional reload directories)
当使用 debug
或者是 auto-reload
时,您可以指定额外的目录来确保这些目录中的文件发生变动时重启 Sanic 应用。
sanic ... --reload-dir=/path/to/foo --reload-dir=/path/to/bar
提示
您不需要指定应用所在的目录。Sanic 将会自动的检测应用目录下 Python 文件的变化并重启。您应该使用 reload-dir
参数来指定其他您关心的静态文件,并且在这些文件变化时通知应用重启。
# 版本前缀(Version prefix)
当使用了 version
参数时,您的路由会自动添加 /v<YOUR_VERSION_NUM>
的前缀。这并不是新的功能。
# /v1/my/path
app.route("/my/path", version=1)
现在,您可以通过在版本信息之前添加额外的路径信息的方式来可以修改这个固定前缀。
# /api/v1/my/path
app.route("/my/path", version=1, version_prefix="/api/v")
version_prefix
参数可以这么使用:
- 使用
app.route
和bp.route
装饰器(以及所有其他装饰器)时 - 创建
Blueprint
对象时 - 调用
Blueprint.group
函数时 - 创建
BlueprintGroup
对象时 - 使用
app.blueprint
注册蓝图时
# 信号事件的自动注册(Signal event auto-registration)
将配置项 config.EVENT_AUTOREGISTER
设置为 True
时将允许您等待任何的信号事件,即使这些信号没有被注册到一个响应函数上。
@app.signal("do.something.start")
async def signal_handler():
await do_something()
await app.dispatch("do.something.complete")
# somethere else in your app:
await app.event("do.something.complete")
# 可重复利用和可嵌套的 Blueprint
和 BlueprintGroup
(Infinitely reusable and nestable Blueprint
and BlueprintGroup
)
单独的 Blueprint
可能不会被多个蓝图组重复注册。但是蓝图组本身可以被循环嵌套至一个或多个其他组。这将消除了蓝图组构成方式的限制。
# HTTP 方法作为 Enum
(HTTP methods as Enum
)
Sanic 现在设置了 sanic.HTTPMethod
的 Enum
枚举对象。它可以与字符串交替使用。
from sanic import Sanic, HTTPMethod
@app.route("/", methods=["post", "PUT", HTTPMethod.PATCH])
async def handler(...):
...
# 拓展 HTTPMethodView
(Expansion of HTTPMethodView
)
基于类的视图现在拥有以下三种关联app的方式:
方式1 - 现有的
class DummyView(HTTPMethodView):
...
app.add_route(DummyView.as_view(), "/dummy")
方式2 - 使用 attach
方法关联
class DummyView(HTTPMethodView):
...
DummyView.attach(app, "/")
方式3 - 定义类时使用 __init_subclass__
方法关联
class DummyView(HTTPMethodView, attach=app, uri="/"):
...
如果您您的视图定义在其他文件中,方式2和方式3将会比较有用:
from sanic import Sanic, HTTPMethodView
class DummyView(HTTPMethodView, attach=Sanic.get_app(), uri="/"):
...
# 新闻(News)
# Discord 聊天室和社区论坛 (Discord and support forums)
如果您还没有加入我们的社区,您可以通过加入Discord服务器 (opens new window)和社区论坛 (opens new window)来参与社区讨论。此外,别忘了在Twitter上关注@sanicframework (opens new window)。
# Sanic 社区组织 2022 年选举(SCO 2022 elections)
这个 夏天🏝 / 冬天❄️(根据您所在的半球)即将来临。这意味着我们将举行 Sanic 社区组织的选举。今年,我们将有以下职位需要填补:
- 指导委员会成员 (任期2年)
- 指导委员会成员(任期2年)
- 指导委员会成员(任期1年)
- v22版本发布经理
- v22版本发布经理
@vltr (opens new window) 将继续担任指导委员会,完成他第二年的工作。
如果您有兴趣了解更多信息,您可以阅读有关 SCO 角色和责任 或在 Discord 上的找 Adam Hopkins 了解详细情况。
提名将于 9 月 1 日开始。随着选举的来临,更多的信息将在论坛上发布。
# 正在进行的新项目(New project underway)
我们在 SCO 的名下增加了一个新项目:sanic-ext
(opens new window)。该项目尚未发布,并处于积极开发中。这个项目的目标是最终取代sanic-openapi
(opens new window),为 Web 应用开发者提供更多的功能,包括参数校验、CORS 和 HTTP自动响应。如果您有兴趣帮忙,请在 Discord 上告诉我们。我们希望在 9 月份的发布之前看到该项目的初始版本。
# 鸣谢(Thank you)
感谢所有参与本次发布的人:👏
@aaugustin (opens new window) @ahopkins (opens new window) @ajaygupta2790 (opens new window) @ashleysommer (opens new window) @ENT8R (opens new window) @fredlllll (opens new window) @graingert (opens new window) @harshanarayana (opens new window) @jdraymon (opens new window) @Kyle-Verhoog (opens new window) @sanjeevanahilan (opens new window) @sjsadowski (opens new window) @Tronic (opens new window) @vltr (opens new window) @ZinkLu (opens new window)
如果您喜欢本项目,请考虑参与建设本项目。我们欢迎您提交代码,也欢迎您以任何其他方式来参与本项目的建设。比如撰写文档,分享使用心得,参与社区讨论,当然,如果经济允许,您也可以考虑经济资助 (opens new window)。