摘要:也就是說,是連接服務器和應用服務器的橋梁。目前實現的中,有兩個角色分別是和。是一個可調用對象,它包含了一個表示響應狀態的字符串和一個響應的列表以及一個用于出錯返回的信息,具體參數包含及詳情請點這里。可以被連接在一起,由此產生的鏈通常被稱為。
首先,什么是WSGI?
WSGI, 全稱為 Web Server Gateway Interface。
它不是什么框架,它是一個規范,但是作為一個規范,它實際上并沒有官方標準。
這里要說明一下,PEP-0333并不是用來規范WSGI用得,而是PEP-0333提出應該有那么一個東西用來處理web服務器和應用服務器之間的關系,因此產生了WSGI。
因為,就目前來看,Web服務一般按照如下方式部署:
先部署一個web服務器(Apache etc.)用于處理協議層的業務,比如,單臺物理機多服務(多域名或者多端口)、負載均衡等。
然后部署一個應用服務器(Django etc.),它用于處理具體業務方面的事情,比如,滴滴打車的應用服務器就會處理打車訂單CRUD,處理完成之后呢再返回給web服務器,web服務器收到響應之后再返回給客戶端。
WSGI是如何工作的?通過上文,我們可以了解到WSGI無非做了兩件事:
讓Web服務器知道如何調用Python應用程序并把從客戶端來的請求拿過來。
讓Python應用程序知道客戶端的具體請求是什么,以及如何返回結果給Web服務器并幫助Python應用程序把計算后的結果返回給Web服務器。
也就是說,WSGI是連接Web服務器和應用服務器的橋梁。
目前實現的WSGI中,有兩個角色,分別是Server/Gateway和application/framework。
當請求來臨的時候,server調用application,然后application把結果返回給server。
那么,server是如何調用application的?接下來,server需要知道去哪能夠找到application。實現這一邏輯,需要在server指定一個Python模塊(具體在server的哪個位置保存這一路徑,那就得根據具體server類型來選擇了,如apache或nginx)該模塊必須包含一個名稱為application的可調用對象,這個對象的形式如下:
在PEP-0333中指出了,一個WSGI的application角色,應該是一個可調用對象:
def application(environ, start_response)
其中,environ是一個包含了關于這次HTTP請求信息的字典,start_response是一個可調用對象,用于在application中執行,用以在返回響應內容前設置響應的狀態碼和響應頭,同時也意味著告訴server,application要開始返回http的body了。這兩個就是server調用application時候需要傳遞的所有參數了。
那么,我們還需要再說一下,environ和start_response()是需要在server端的生成和定義的
有了這兩個參數,application就能知道用戶請求的是什么資源,請求中帶了什么數據,結果該如何返回給server等等。其中,environ包含了一些符合CGI規范的環境變量和WSGI規范新添加的變量,此外還可能有一些系統變量及Web服務器相關的環境變量。start_response是一個可調用對象,它包含了一個表示HTTP響應狀態的字符串和一個HTTP響應headers的列表以及一個用于出錯返回的信息,具體參數包含及詳情請點這里。
下面是一個完整的application demo,最終返回的body也可以是一個可迭代對象,這樣server也可以通過遍歷這個對象來拼接成body。
def application(environ, start_response): start_response("200 OK", [("Content-type", "text/plain")]) return ["Hello World!",]
看上去不錯,那么我們該如何調用呢?
有幾個服務器組件也能夠運行的WSGI應用程序,但是對于簡單的測試目的,我們可以使用包含在Python的標準庫參考實現,就像下面那樣:
if __name__ == "__main__": from wsgiref.simple_server import make_server server = make_server("localhost", 8080, application) server.serve_forever()
好了,還記得我們剛才提到的最終返回的body也可以是一個可迭代對象嗎?在python中,創建一個迭代器的簡單辦法就是使用一個生成器,比如,我們有一個用于靜態文件的服務,我們可以寫一個生成器,讓它一次生成一個固定大小的文件塊,這樣我們就可以隨時一次只存儲一個文件塊了,讓我們來試試吧:
def send_file(file_path, size): with open(file_path) as f: block = f.read(BLOCK_SIZE) while block: yield block block = f.read(BLOCK_SIZE)
對應的 WSGI application 部分如下:
size = os.path.getsize(file_path) headers = [ ("Content-type", mimetype), ("Content-length", str(size)), ] start_response("200 OK", headers) return send_file(file_path, size)
注意,send_file就是上文中所指的可迭代對象。
WSGI中間件看得出來,WSGI應用結構非常簡潔,只需指定一個可調用的識別標記,這使得WSGI應用很容易實現調用其他框架,無非就是修改到來的請求或者修改發出的響應,當然也可以兩者都有。那么,接下來看看demo:
class Filter(object): def __init__(self, application): self.application = application def __call__(self, environ, start_response): # Do something here to modify request pass # Call the wrapped application app_iter = self.application(environ, self._sr_callback(start_response)) # Do something to modify the response body pass # Return modified response return app_iter def _sr_callback(self, start_response): def callback(status, headers, exc_info=None): # Do something to modify the response status or headers pass # Call upstream start_response start_response(status, headers, exc_info) return callback
像這樣應用通常被稱為Middleware applications或Filter。 Filter可以被連接在一起,由此產生的鏈通常被稱為pipeline。
最后呢,我想說明一下,WSGI是故意設計成最小的Web服務器實現輕松的應用,以便被更多的人采用。但是,幾乎沒有人真的喜歡直接操作environ變量,也幾乎沒有人喜歡用start_response這么詭異的邏輯,雖然WSGI提供的API易于實現,但這不代表它的語義讓人滿意。也正是因為這一原因,幾乎每一個應用程序或者web框架都把environ和start_response封裝成了語義更完善容錯率更高的request和response對象。
Webob就是request和response對象的規范實現之一,它使得WSGI更容易和更滿意地被大家使用。
你可以在這里找到Webob的官方文檔,當然,下次有機會我也會簡單的說明一下Webob到底有多方便。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/37668.html
摘要:線程局部變量,也就是每個線程的私有變量,具有線程隔離性。按我們正常的理解,應該是每一個請求對應一個處理線程。在中,除了線程之外,還有個叫協程的東東,這里不提進程。配合會確保不管是協程還是線程,只要當前請求處理完成之后清除中對應的內容。 首先貼出官方文檔地址:http://werkzeug.pocoo.org/doc...幾個local?threading.localwerkzeug.l...
摘要:在介紹之前,先介紹一下,它為語言定義的服務器和應用程序或框架之間的一種簡單而通用的接口。這個函數接受兩個參數,分別是和。響應對象是一個應用,提供了更好的方法來創建響應。這部分解釋來源于官方文檔的中文版。 Werkzeug 是一個WSGI工具包,也可以作為一個Web框架的底層庫。 WSGI 在介紹Werkzeug之前,先介紹一下 WSGI(Python Web Server Gate...
摘要:一般來說,這一例行程序用于處理請求的每一部分,例如把路徑作為一系列字典鍵值進行處理。,必須是按照中所規定地鍵值元組列表。行為時回車換行。這個包裝器也可能用模塊指明那些有問題的,但不完全違反的行為。 wsgirf-WSGI功能及參考實現 源碼:Lib/wsgiref Web服務器網關接口(Web Server Gateway Interface, WSGI),是用Python寫的一個服務...
摘要:通過回調函數將響應狀態和響應頭返回給,同時返回響應正文,響應正文是可迭代的并包含了多個字符串。返回響應正文負責獲取請求,將請求傳遞給,由處理請求后返回。 我想大部分Python開發者最先接觸到的方向是WEB方向(因為總是有開發者希望馬上給自己做個博客出來,例如我),既然是WEB,免不了接觸到一些WEB框架,例如Django,Flask,Torando等等,在開發過程中,看過一些文檔總會...
閱讀 1141·2021-11-23 10:04
閱讀 2401·2021-11-22 15:29
閱讀 2743·2021-11-19 09:40
閱讀 715·2021-09-22 15:26
閱讀 2117·2019-08-29 16:27
閱讀 2484·2019-08-29 16:10
閱讀 1918·2019-08-29 15:43
閱讀 3275·2019-08-29 12:43