亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

淺析WSGI

王偉廷 / 2506人閱讀

摘要:也就是說(shuō),是連接服務(wù)器和應(yīng)用服務(wù)器的橋梁。目前實(shí)現(xiàn)的中,有兩個(gè)角色分別是和。是一個(gè)可調(diào)用對(duì)象,它包含了一個(gè)表示響應(yīng)狀態(tài)的字符串和一個(gè)響應(yīng)的列表以及一個(gè)用于出錯(cuò)返回的信息,具體參數(shù)包含及詳情請(qǐng)點(diǎn)這里??梢员贿B接在一起,由此產(chǎn)生的鏈通常被稱為。

首先,什么是WSGI?

WSGI, 全稱為 Web Server Gateway Interface。

它不是什么框架,它是一個(gè)規(guī)范,但是作為一個(gè)規(guī)范,它實(shí)際上并沒有官方標(biāo)準(zhǔn)。
這里要說(shuō)明一下,PEP-0333并不是用來(lái)規(guī)范WSGI用得,而是PEP-0333提出應(yīng)該有那么一個(gè)東西用來(lái)處理web服務(wù)器和應(yīng)用服務(wù)器之間的關(guān)系,因此產(chǎn)生了WSGI。

其次,為什么PEP-0333覺得需要這個(gè)規(guī)范呢?

因?yàn)?,就目前?lái)看,Web服務(wù)一般按照如下方式部署:

先部署一個(gè)web服務(wù)器(Apache etc.)用于處理協(xié)議層的業(yè)務(wù),比如,單臺(tái)物理機(jī)多服務(wù)(多域名或者多端口)、負(fù)載均衡等。

然后部署一個(gè)應(yīng)用服務(wù)器(Django etc.),它用于處理具體業(yè)務(wù)方面的事情,比如,滴滴打車的應(yīng)用服務(wù)器就會(huì)處理打車訂單CRUD,處理完成之后呢再返回給web服務(wù)器,web服務(wù)器收到響應(yīng)之后再返回給客戶端。

WSGI是如何工作的?

通過(guò)上文,我們可以了解到WSGI無(wú)非做了兩件事:

讓W(xué)eb服務(wù)器知道如何調(diào)用Python應(yīng)用程序并把從客戶端來(lái)的請(qǐng)求拿過(guò)來(lái)。

讓Python應(yīng)用程序知道客戶端的具體請(qǐng)求是什么,以及如何返回結(jié)果給Web服務(wù)器并幫助Python應(yīng)用程序把計(jì)算后的結(jié)果返回給Web服務(wù)器。

也就是說(shuō),WSGI是連接Web服務(wù)器和應(yīng)用服務(wù)器的橋梁。

目前實(shí)現(xiàn)的WSGI中,有兩個(gè)角色,分別是Server/Gatewayapplication/framework。

當(dāng)請(qǐng)求來(lái)臨的時(shí)候,server調(diào)用application,然后application把結(jié)果返回給server。

那么,server是如何調(diào)用application的?

接下來(lái),server需要知道去哪能夠找到application。實(shí)現(xiàn)這一邏輯,需要在server指定一個(gè)Python模塊(具體在server的哪個(gè)位置保存這一路徑,那就得根據(jù)具體server類型來(lái)選擇了,如apache或nginx)該模塊必須包含一個(gè)名稱為application的可調(diào)用對(duì)象,這個(gè)對(duì)象的形式如下:

PEP-0333中指出了,一個(gè)WSGI的application角色,應(yīng)該是一個(gè)可調(diào)用對(duì)象:

def application(environ, start_response)

其中,environ是一個(gè)包含了關(guān)于這次HTTP請(qǐng)求信息的字典,start_response是一個(gè)可調(diào)用對(duì)象,用于在application中執(zhí)行,用以在返回響應(yīng)內(nèi)容前設(shè)置響應(yīng)的狀態(tài)碼和響應(yīng)頭,同時(shí)也意味著告訴server,application要開始返回http的body了。這兩個(gè)就是server調(diào)用application時(shí)候需要傳遞的所有參數(shù)了。

那么,我們還需要再說(shuō)一下,environstart_response()是需要在server端的生成和定義的

有了這兩個(gè)參數(shù),application就能知道用戶請(qǐng)求的是什么資源,請(qǐng)求中帶了什么數(shù)據(jù),結(jié)果該如何返回給server等等。其中,environ包含了一些符合CGI規(guī)范的環(huán)境變量和WSGI規(guī)范新添加的變量,此外還可能有一些系統(tǒng)變量及Web服務(wù)器相關(guān)的環(huán)境變量。start_response是一個(gè)可調(diào)用對(duì)象,它包含了一個(gè)表示HTTP響應(yīng)狀態(tài)的字符串和一個(gè)HTTP響應(yīng)headers的列表以及一個(gè)用于出錯(cuò)返回的信息,具體參數(shù)包含及詳情請(qǐng)點(diǎn)這里。

下面是一個(gè)完整的application demo,最終返回的body也可以是一個(gè)可迭代對(duì)象,這樣server也可以通過(guò)遍歷這個(gè)對(duì)象來(lái)拼接成body。

def application(environ, start_response):
    start_response("200 OK", [("Content-type", "text/plain")])
    return ["Hello World!",]

看上去不錯(cuò),那么我們?cè)撊绾握{(diào)用呢?

有幾個(gè)服務(wù)器組件也能夠運(yùn)行的WSGI應(yīng)用程序,但是對(duì)于簡(jiǎn)單的測(cè)試目的,我們可以使用包含在Python的標(biāo)準(zhǔn)庫(kù)參考實(shí)現(xiàn),就像下面那樣:

if __name__ == "__main__":
    from wsgiref.simple_server import make_server
    server = make_server("localhost", 8080, application)
    server.serve_forever()

好了,還記得我們剛才提到的最終返回的body也可以是一個(gè)可迭代對(duì)象嗎?在python中,創(chuàng)建一個(gè)迭代器的簡(jiǎn)單辦法就是使用一個(gè)生成器,比如,我們有一個(gè)用于靜態(tài)文件的服務(wù),我們可以寫一個(gè)生成器,讓它一次生成一個(gè)固定大小的文件塊,這樣我們就可以隨時(shí)一次只存儲(chǔ)一個(gè)文件塊了,讓我們來(lái)試試吧:

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)

對(duì)應(yīng)的 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就是上文中所指的可迭代對(duì)象。

WSGI中間件

看得出來(lái),WSGI應(yīng)用結(jié)構(gòu)非常簡(jiǎn)潔,只需指定一個(gè)可調(diào)用的識(shí)別標(biāo)記,這使得WSGI應(yīng)用很容易實(shí)現(xiàn)調(diào)用其他框架,無(wú)非就是修改到來(lái)的請(qǐng)求或者修改發(fā)出的響應(yīng),當(dāng)然也可以兩者都有。那么,接下來(lái)看看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

像這樣應(yīng)用通常被稱為Middleware applicationsFilter。 Filter可以被連接在一起,由此產(chǎn)生的鏈通常被稱為pipeline。

最后呢,我想說(shuō)明一下,WSGI是故意設(shè)計(jì)成最小的Web服務(wù)器實(shí)現(xiàn)輕松的應(yīng)用,以便被更多的人采用。但是,幾乎沒有人真的喜歡直接操作environ變量,也幾乎沒有人喜歡用start_response這么詭異的邏輯,雖然WSGI提供的API易于實(shí)現(xiàn),但這不代表它的語(yǔ)義讓人滿意。也正是因?yàn)檫@一原因,幾乎每一個(gè)應(yīng)用程序或者web框架都把environstart_response封裝成了語(yǔ)義更完善容錯(cuò)率更高的request和response對(duì)象。

Webob就是request和response對(duì)象的規(guī)范實(shí)現(xiàn)之一,它使得WSGI更容易和更滿意地被大家使用。

你可以在這里找到Webob的官方文檔,當(dāng)然,下次有機(jī)會(huì)我也會(huì)簡(jiǎn)單的說(shuō)明一下Webob到底有多方便。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/37668.html

相關(guān)文章

  • Werkzeug Local與LocalProxy等淺析

    摘要:線程局部變量,也就是每個(gè)線程的私有變量,具有線程隔離性。按我們正常的理解,應(yīng)該是每一個(gè)請(qǐng)求對(duì)應(yīng)一個(gè)處理線程。在中,除了線程之外,還有個(gè)叫協(xié)程的東東,這里不提進(jìn)程。配合會(huì)確保不管是協(xié)程還是線程,只要當(dāng)前請(qǐng)求處理完成之后清除中對(duì)應(yīng)的內(nèi)容。 首先貼出官方文檔地址:http://werkzeug.pocoo.org/doc...幾個(gè)local?threading.localwerkzeug.l...

    The question 評(píng)論0 收藏0
  • Werkzeug 與 WSGI 介紹

    摘要:在介紹之前,先介紹一下,它為語(yǔ)言定義的服務(wù)器和應(yīng)用程序或框架之間的一種簡(jiǎn)單而通用的接口。這個(gè)函數(shù)接受兩個(gè)參數(shù),分別是和。響應(yīng)對(duì)象是一個(gè)應(yīng)用,提供了更好的方法來(lái)創(chuàng)建響應(yīng)。這部分解釋來(lái)源于官方文檔的中文版。 Werkzeug 是一個(gè)WSGI工具包,也可以作為一個(gè)Web框架的底層庫(kù)。 WSGI 在介紹Werkzeug之前,先介紹一下 WSGI(Python Web Server Gate...

    mengera88 評(píng)論0 收藏0
  • 通讀Python官方文檔之wsgiref(未完成)

    摘要:一般來(lái)說(shuō),這一例行程序用于處理請(qǐng)求的每一部分,例如把路徑作為一系列字典鍵值進(jìn)行處理。,必須是按照中所規(guī)定地鍵值元組列表。行為時(shí)回車換行。這個(gè)包裝器也可能用模塊指明那些有問題的,但不完全違反的行為。 wsgirf-WSGI功能及參考實(shí)現(xiàn) 源碼:Lib/wsgiref Web服務(wù)器網(wǎng)關(guān)接口(Web Server Gateway Interface, WSGI),是用Python寫的一個(gè)服務(wù)...

    mumumu 評(píng)論0 收藏0
  • Python Web開發(fā)最難懂的WSGI協(xié)議,到底包含哪些內(nèi)容?

    摘要:通過(guò)回調(diào)函數(shù)將響應(yīng)狀態(tài)和響應(yīng)頭返回給,同時(shí)返回響應(yīng)正文,響應(yīng)正文是可迭代的并包含了多個(gè)字符串。返回響應(yīng)正文負(fù)責(zé)獲取請(qǐng)求,將請(qǐng)求傳遞給,由處理請(qǐng)求后返回。 我想大部分Python開發(fā)者最先接觸到的方向是WEB方向(因?yàn)榭偸怯虚_發(fā)者希望馬上給自己做個(gè)博客出來(lái),例如我),既然是WEB,免不了接觸到一些WEB框架,例如Django,Flask,Torando等等,在開發(fā)過(guò)程中,看過(guò)一些文檔總會(huì)...

    atinosun 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<