python 內(nèi)置庫wsgiref的使用(WSGI基礎(chǔ)入門)
WSGI基本原理
1. WSGI處理過程
- 瀏覽器到WSGI Server:瀏覽器發(fā)送的請求會先到WSGI Server。
- environ:WSGI Server會將HTTP請求中的參數(shù)等信息封裝到environ(一個字典)中。
- WSGI Server到WSGI App:App就是我們自己編寫的后臺程序,每個URL會映射到對應(yīng)的入口處理函數(shù)(或其他可調(diào)用對象),WSGI Server調(diào)用后臺App時,會將environ和WSGI Server中自己的一個start_response函數(shù)注入到后臺App中。
- 邏輯處理:后臺函數(shù)(或其他可調(diào)用對象)需要接收environ和start_response,進行邏輯處理后返回一個可迭代對象,可迭代對象中的元素為HTTP正文。
- WSGI App到WSGI Server:后臺函數(shù)處理完后,會先調(diào)用start_response函數(shù)將HTTP狀態(tài)碼、報文頭等信息(響應(yīng)頭)返回給WSGI Server,然后再將函數(shù)的返回值作為HTTP正文(響應(yīng)body)返回給WSGI Server。
- WSGI Server到瀏覽器:WSGI Server將從App中得到的所有信息封裝為一個response返回給瀏覽器。
2. WSGI示例
wsgiref簡單示例
運行以下示例程序后,在瀏覽器中輸入以http://127.0.0.1:9999/開頭的隨意一個url都可以看到返回結(jié)果。實例程序中所有url都會以同一個App進行處理,實際生產(chǎn)環(huán)境中不同的url肯定是需要映射到不同的App上的,但這部分本文不作講解。
# wsgiref是Python自帶的內(nèi)置庫,它用來開發(fā)者對wsgi進行測試用的,不可以用在生產(chǎn)環(huán)境中 from wsgiref.simple_server import make_server, demo_app # wsgi也是基于socket server編寫 # 默認(rèn)情況下會將所有url都傳入demo_app進行處理,具體可參考demo_app源碼 # app參數(shù)可以是任何可調(diào)用對象,但是內(nèi)部處理需要參考demo_app源碼,即environ處理、start_response調(diào)用、返回值類型 ws = make_server('127.0.0.1', 9999, demo_app) # 啟動服務(wù) ws.serve_forever()
demo_app源碼
def demo_app(environ,start_response): from io import StringIO stdout = StringIO() print("Hello world!", file=stdout) print(file=stdout) # environ是一個字典,包含了所有請求信息 h = sorted(environ.items()) for k,v in h: print(k,'=',repr(v), file=stdout) # return之前需要調(diào)用start_response設(shè)置響應(yīng)頭信息 start_response("200 OK", [('Content-Type','text/plain; charset=utf-8')]) return [stdout.getvalue().encode("utf-8")] # 一個可迭代對象,元素為byte類型,元素內(nèi)容依據(jù)start_response中指定的Content-Type來指定
demo_app類定義的兩種方式
# 第一種方式:定義類的__init__和__iter__方法,前者用來接收和處理environ和start_response,后者生成一個可迭代對象 # make_server中app參數(shù)只需傳入類名即可 class ApplicationClass: def __init__(self, environ, start_response): self.e = environ self.sr = start_response def __iter__(self): from io import StringIO stdout = StringIO() print("Hello world!", file=stdout) print(file=stdout) h = sorted(self.e.items()) for k, v in h: print(k, '=', repr(v), file=stdout) self.sr("200 OK", [('Content-Type', 'text/plain; charset=utf-8')]) yield from [stdout.getvalue().encode("utf-8")] # 第二種方式:定義__call__方法,接收和處理environ和start_response,并返回一個可迭代對象 # make_server中app參數(shù)需要傳入類的實例 class ApplicationInstance: def __call__(self, environ, start_response): from io import StringIO stdout = StringIO() print("Hello world!", file=stdout) print(file=stdout) h = sorted(environ.items()) for k, v in h: print(k, '=', repr(v), file=stdout) start_response("200 OK", [('Content-Type', 'text/plain; charset=utf-8')]) return [stdout.getvalue().encode("utf-8")]
3. WSGI web服務(wù)器和應(yīng)用程序
WSGI web服務(wù)器
- 本質(zhì)上是一個TCP服務(wù)器,監(jiān)聽在特定的端口上。
- 支持HTTP協(xié)議,能夠解析HTTP請求報文,能夠按HTTP協(xié)議將響應(yīng)數(shù)據(jù)封裝為報文并返回給瀏覽器。
- 實現(xiàn)了WSGI協(xié)議,該協(xié)議約定了和應(yīng)用程序之間的接口,即url到app之間的映射。
WSGI應(yīng)用程序
- 遵從WSGI協(xié)議。
- 本身是一個可調(diào)用對象。
- 調(diào)用start_response,返回響應(yīng)頭部。
- 返回包含正文的可迭代對象。
以上就是python 內(nèi)置庫wsgiref的使用(WSGI基礎(chǔ)入門)的詳細內(nèi)容,更多關(guān)于python wsgiref的使用的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
python 定時任務(wù)去檢測服務(wù)器端口是否通的實例
今天小編就為大家分享一篇python 定時任務(wù)去檢測服務(wù)器端口是否通的實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-01-01Python內(nèi)置庫之webbrowser模塊用法詳解
webbrowser模塊是Python自帶的標(biāo)準(zhǔn)庫,無需安裝,可以直接在Python中使用該模塊來打開網(wǎng)頁、PDF文件等,本文給大家詳細介紹了Python webbrowser模塊用法,需要的朋友可以參考下2023-08-08基于python實現(xiàn)地址和經(jīng)緯度轉(zhuǎn)換
這篇文章主要介紹了基于python實現(xiàn)地址和經(jīng)緯度轉(zhuǎn)換,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-05-05Python的Socket編程過程中實現(xiàn)UDP端口復(fù)用的實例分享
這篇文章主要介紹了Python的Socket編程過程中實現(xiàn)UDP端口復(fù)用的實例分享,文中作者用到了Python的twisted異步框架,需要的朋友可以參考下2016-03-03PyTorch中的神經(jīng)網(wǎng)絡(luò) Mnist 分類任務(wù)
這篇文章主要介紹了PyTorch中的神經(jīng)網(wǎng)絡(luò) Mnist 分類任務(wù),在本次的分類任務(wù)當(dāng)中,我們使用的數(shù)據(jù)集是 Mnist 數(shù)據(jù)集,這個數(shù)據(jù)集大家都比較熟悉,需要的朋友可以參考下2023-03-03解決pytorch下出現(xiàn)multi-target not supported at的一種可能原因
這篇文章主要介紹了解決pytorch下出現(xiàn)multi-target not supported at的一種可能原因,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2021-02-02