首頁  >  文章  >  後端開發  >  ASGI解釋:Python Web開發的未來

ASGI解釋:Python Web開發的未來

WBOY
WBOY轉載
2023-04-12 22:37:031486瀏覽

譯者| 李睿

審校| 孫淑娟

#Python Web應用程式長期以來一直遵循Web伺服器網關介面(WSGI)標準,該標準描述了它們如何與Web伺服器通訊。 WSGI最初於2003年推出,並於2010年更新,僅依賴Python2.2版本中原生可用的、易於實現的功能。因此, WSGI迅速融入了所有主要的Python Web框架,並成為Python Web開發的基石。

快轉到2022年。 Python2已經過時,Python現在具有處理網路呼叫等非同步操作的原生語法。 WSGI和其他預設假定同步行為的標準無法利用非同步的效能和效率增益。這反過來又意味著WSGI不能有效地處理像WebSocket這樣的高階協定。

輸入ASGI,即非同步伺服器閘道介面。與WSGI類似,ASGI描述了Python Web應用程式和Web伺服器之間的通用介面。與WSGI不同的是,ASGI允許每個應用程式有多個非同步事件。另外,ASGI支援同步和非同步應用程式。開發人員可以將原有的同步WSGI Web應用程式遷移到ASGI,也可以使用ASGI建立新的非同步Web應用程式。

1.WSGI的工作原理

WSGI的工作原理是向Web伺服器公開Python函數,通常命名為應用程式或app。此函數採用兩個參數:

  • environ:包含有關目前請求和Web伺服器提供的環境變數的資訊的字典。
  • start_response:將用於啟動將HTTP回應傳送回客戶端的函式。

函數傳回的資料構成回應體。

一個簡單的應用程式函數可能如下所示:

def application(environ, start_response):

 start_response('200 OK', [('Content-Type', 'text/plain')])

 return [b'Greetings universe']

如果使用的是與WSGI相容的Web框架(例如Flask ),那麼框架本身將提供一個應用程式功能,其所有元件將自動連接。

WSGI有兩個缺點:首先,WSGI一次只處理一個請求和回應,並假設回應將立即傳回。沒有辦法處理長時間保持的連接,例如WebSocket或長輪詢HTTP連接。

其次,WSGI只是同步的。即使使用多執行緒連接池,每個連線都會阻塞,直到它回傳回應。許多WSGI設定都能夠處理執行緒池和進程池,但這些都受到WSGI介面本身同步的限制。

2.ASGI的工作原理

ASGI在外觀上與WSGI相似。與WSGI一樣,開發人員可以定義一個應用程式函數對象,但它是一個帶有三個參數而不是兩個參數的非同步函數:

scope:包含有關當前請求的資訊的字典,類似WSGI中的environ,但細節的命名約定略有不同。

send:允許應用程式將訊息傳回客戶端的非同步可呼叫函數。

receive:允許應用程式從客戶端接收訊息的非同步可呼叫函數。

一個簡單的ASGI應用程式函數如下所示:

async def application(scope, receive, send):
 await send({
 'type': 'http.response.start',
 'status': 200,
 'headers': [
 [b'content-type', b'text/plain'],
 ],
 })
 await send({
 'type': 'http.response.body',
 'body': b'Hello, world!',
 })

與WSGI Web框架一樣,ASGI Web框架會產生自己的application ()函數,並根據需要將其連接起來。

與ASGI最明顯的差異是,在整個函數中使用了非同步隱喻。函數本身是異步的,在此透過兩個單獨的await send( )命令發送HTTP標頭和回應正文。這樣,函數本身及其發送命令就不會阻塞任何內容;它們可以與應用程式的呼叫交織在一起,並可以同時從許多其他連接中發送。

在這個範例中沒有使用receive,但它也是一個非同步函數。它讓在不阻塞其他操作的情況下接收請求正文。請求和回應可以以這種方式增量地傳入或傳出伺服器——這是無法很好地完成的事情,或者可能根本無法使用WSGI完成的。

3.在ASGI中使用同步和非同步函數

使用ASGI時,需要盡可能使用非同步函數和非同步友善程式庫。養成使用非同步的習慣是值得的,因為使用僅同步程式碼的問題可能很嚴重。任何對同步函數的長時間呼叫都會阻塞整個呼叫鏈,使使用非同步的好處幾乎消失殆盡。

如果在使用長時間運行的同步呼叫時遇到問題,則需要使用asyncio.run_in_executor將呼叫外包給執行緒池或進程池。每當等待外部事件或非CPU密集型任務時,都應使用執行緒池。而進程池應該用於CPU密集的本地任務。

例如,Web應用程式中有一個路由可以呼叫遠端網站,那麼應該使用執行緒。或者更好的方法是,使用發出非同步HTTP請求的aiohttp函式庫。如果想要呼叫Pillow映像庫來調整映像大小,可能應該使用具有進程池的run_in_executor。儘管在進程之間來回傳輸資料會有一些輕微的開銷,但使用run_in_executor不會阻塞其他事件。

#

4.支持ASGI的Web框架

通过实现application( )对象,可以人工编写ASGI Web应用程序。但绝大多数情况下,使用异步原生、以ASGI为中心的Python Web框架会更简单。以下是一些常见的与ASGI兼容的Web框架:

Starlette和FastAPI:这些新兴框架(FastAPI构建在Starlette之上)都是异步优先的,因此它们都支持ASGI也就不足为奇了。如果是从零开始开发Web应用程序,那么它们是Python最现代和最前沿的Web框架。

Quart:虽然主要的Python Web框架Flask确实支持ASGI,但Flask的设计并不是从内到外利用异步隐喻。来自GitLab的Quart使用Flask的语法和隐喻,但允许异步路由处理程序。

Django 3.0及更高版本:从Django3.0开始,久负盛名的Django Web框架支持ASGI。在Django 3.1中添加了对Django应用程序中异步代码的支持,而不是仅仅能够在ASGI处理程序上挂载Django。对于一个不以执行速度著称的框架来说,异步的存在为那些选择利用它的人带来了更好的性能。

原文链接:https://www.infoworld.com/article/3658336/asgi-explained-the-future-of-python-Web-development.html​

以上是ASGI解釋:Python Web開發的未來的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:51cto.com。如有侵權,請聯絡admin@php.cn刪除