如果你认为Python只在数据科学领域流行,请修正你的观点!Python Web开发又有了新的异步框架,这是很令人兴奋的。
目前,Python Web开发生态系统中出现了许多令人兴奋的事情-这项工作的主要驱动力之一就是ASGI(异步标准网关接口)。
我已经在这里多次提到过ASGI,尤其是在宣布Bocadillo和tartiflette-starlette时,但是我从来没有真正花时间对此库进行详尽的介绍。那就现在开始了!
这篇文章针对的是对Python Web开发的最新方向感兴趣的人。我将详尽的介绍什么是ASGI,和什么是最新的Python Web开发技术。
在开始之前,我顺便宣布一下,我最近创建了awesome-asgi页面,这是一个很全面的列表,可以帮助人们了解不断扩展的ASGI生态系统。
可以在页面上查看关于这些库版本更新。
好吧,现在让我们开始吧!
一切始于async/await语法
与JavaScript或Go相反,Python并不是一开始就引入异步执行的语言。长期以来,只能使用多线程或多进程,或依靠其它的异步网络库(例如eventlet,gevent或Twisted)来实现在Python中并发执行任务。(早在2008年,Twisted已经有了异步协同接口,例如,inlineCallbacks和deferredGenerator。)
但这一切在Python 3.4+中开始改变了。Python的3.4 添加asyncio到标准库,基于generators 和yield from语法,实现对多任务的支持。
后来,在Python 3.5中添加了async/ await语法。依赖于这一语法功能,我们现在实现了独立于底层的原生协程,这为Python并发库的编写打下基础。
自从3.5发布以来,异步库的开发进展迅速,社区一直在对很多的库进行异步处理。如果你有兴趣了解,可以在aio-libs和awesome-asyncio中看到很多项目。
好吧,您猜对了 -- 这也意味着Python Web服务器和应用程序正在向async迈进。实际上,所有很酷的应用都在做!(甚至是Django。)
ASGI概述
那么ASGI如何适合所有这些?
从较高的角度来看,可以将ASGI视为允许Python异步服务器和应用程序间相互通信的工具。它与WSGI有许多共同的设计思想,并且通常以内置异步继承者的形式出现。
这是此模型工作的原理图:
从高层次上看,ASGI是应用程序和服务器之间的通信接口。
但实际上,这要复杂得多。
为了了解ASGI的真正工作原理,让我们看一下ASGI规范:
ASGI包含两个不同的组件:
- 一个协议服务器,其终止Socket协议,并将它们转换成连接和每个连接的事件消息。
- 一个应用程序,驻留在协议服务器中,每个连接中实例化一次,并在事件消息发生时对其进行处理。
因此,根据规范,ASGI真正的要点是消息格式,以及如何在应用程序与运行它的协议服务器之间交换这些消息。
现在,我们可以将图修改为更详细的版本:
真实的ASGI如何工作
显然,还有许多有趣的细节可以看看。例如,可以看一下HTTP和WebSocket的规范。
此外,尽管该规范侧重于服务器和应用程序间的通信,但事实表明ASGI包含的内容不止于此。
我们将在后文说明这些,但首先要说些基础知识…
ASGI的基础
我们已经了解了ASGI如何适用于Python网络生态系统,那么让我们仔细看看具体的代码。
ASGI依靠简单的工作模式:当客户端连接到服务器时,我们实例化一个应用程序。然后,我们将传入的数据输入到应用程序中,然后将所有返回的数据发送回去。
这里所说的 “输入应用程序”实际上有点像调用函数一样调用该应用程序,即输入一些数据并返回输出数据。
实际上,这就是ASGI应用程序的全部特性– 可调用的。同样,此可调用对象的形式由ASGI规范定义。格式如下:
该函数的签名是ASGI中“ I”的含义:应用程序必须实现该接口,服务器才能调用它。
解释一下三个参数:
- scope是一个字典,其中包含有关传入请求的信息。其数据与HTTP和WebSocket连接间的数据有所不同。
- receive是用于接收ASGI事件消息的异步函数。
- send 是用于发送ASGI事件消息的异步函数。
从本质上讲,这些参数可以允许你在运行于协议服务器的通信信道上接收receive()和发送send()数据,通道在此语境下创建。
我不了解你的意见,但是此界面的整体思路和设计形式非常适合我的思维。是时候展示示例代码了。
给我看看你的代码!
为了更实际地了解ASGI的形式外观,我创建了一个很小的项目,展示了uvicorn(流行的ASGI服务器)提供的原生的ASGI HTTP应用程序:
在这里,我们用send()向客户端发送HTTP响应:首先发送Header,然后发送响应主体。
现在,就有了所有这些字典和原始字节数据,我将承认使用原生的ASGI并不是很易用。
幸运的是,还有更高级的选择--是时候开始谈论Starlette。
Starlette是一个优秀的项目,其中的IMO是ASGI生态系统的基础。
简而言之,它提供了一个高级组件的工具箱,例如请求和响应,可用于抽象化ASGI的某些细节。请看Starlette的Hello World:
Starlette具有所有期望的实际Web框架中的全部功能--路由,中间件等。展示一下简单示例,以展示ASGI的真正魅力,请继续看……
”Turtles all down down“
关于ASGI 的有趣而彻底的改变生态的概念是“ Turtles all down down ”,这是迁移Django的人,也是Django异步改造者安德鲁·戈德温(Andrew Godwin)最初创造的(也许是吧?)。
但这到底是什么意思?
因为ASGI是一种抽象概念,它允许在一定的语境下,在任何时候接收和发送数据,有了这种思路,ASGI不仅可用于服务器和应用程序之间交换数据,也可以在堆栈中的任何位置交换数据。
例如,Starlette Response对象本身就是 ASGI应用程序。事实上,我们可以将前面的Starlette示例应用程序简化如下:
那是多么有趣?
但是等等,还有更多的。
”Turtles all down down“更深的含义是,我们可以构建各种应用程序,中间件,库和其他项目,并确保它们都可以实现互操作,只要它们都实现了ASGI应用程序接口即可。
(此外,根据我自己构建Bocadillo的经验,通常(也许始终是)采用ASGI接口会使得代码更简洁。)
例如,我们可以构建一个ASGI中间件(即包装另一个应用程序的应用程序)来显示请求送达的时间:
要使用它,我们只需将其包装在一个应用程序中即可…
……它会很神奇地工作。
令人感到惊奇的是,TimingMiddleware可以包装任何 ASGI应用程序。包装内部应用程序也非常简单,而且可用于成熟的,已有的项目(数百个API和WebSocket端点),不管怎样的项目,只要它与ASGI兼容即可。
(有一个这样一个更适合生产环境的计时中间件:timing-asgi。)
我为什么要在乎?
尽管我认为互操作性是一个重要卖点,但使用基于ASGI的组件构建Python Web应用程序还有许多其它的优点。
- 速度:ASGI应用程序和服务器的异步特性使它们确实运行非常快(至少对于Python而言)--我们正在谈论60k-70k req / s(考虑到Flask和Django在类似情况下只能达到10-20k)。
- 功能:ASGI服务器和框架使你能够访问已有的并发功能(WebSocket,服务器发送事件,HTTP / 2),而这些功能无法使用sync / WSGI来实现。
- 稳定性:ASGI作为一种规范已经存在了大约三年,并且一般认为3.0版是非常稳定的。因而生态系统的基础部分正在稳定。
在库和工具方面,我认为我们不能说我们止步于此。但是,因为有一个非常活跃的社区,我非常希望ASGI生态系统能够与传统的sync / WSGI生态系统实现功能平衡。
在哪里可以找到与ASGI兼容的组件?
实际上,越来越多的人正在构建和改进围绕ASGI建立的项目。包括服务器和Web框架,也包括中间件和面向产品的应用程序,例如Datasette。
我最欣赏的一些非Web框架组件是:
- Mangum:支持AWS Lambda的ASGI
- datasette-auth-github:用于GitHub身份验证的ASGI应用程序
- tartiflette-starlette(我写的这篇文章!):支持Tartiflette的ASGI,一个异步GraphQL引擎。
看到生态系统蓬勃发展虽然感觉很好,但我个人一直很难关注到所有的进展。
如本文开头所写的,我创建了awesome-asgi,原因正是如此。我希望它可以帮助每个人了解ASGI生态中发生的所有令人兴奋的事情。(看到它在几天内几乎达到了100颗星,我感觉确实有必要对ASGI资源进行定位共享。)
总结
尽管它看起来像一个细小的功能,但我确实认为ASGI为新时代的Python Web开发打下了基础。
如果您想了解有关ASGI的更多信息,请参阅awesome-asgi中列出的各种内容(文章和演讲)。如果你想参与其中,请参考以下任何项目:
- uvicorn:ASGI服务器。
- Starlette:ASGI框架。
- TypeSystem:数据验证和表单渲染
- Databases:异步数据库库。
- orm:异步ORM。
- HTTPX:异步HTTP客户端,支持调用ASGI应用程序(用作测试客户端)。
这些项目是由Encode(主要是Tom Christie)构建和维护的。这里有关于建立Encode维护团队的公开讨论,因此,如果您正在寻找机会来促进开源基础进步,那就看看这里!
享受您的ASGI旅程。