一、WSGI簡介
WSGI(Web Server Gateway Interface,web服務器網關介面)主要規定了服務器端和應用程式之間的介面,即規定了請求的URL到后臺處理函式之間的映射該如何實作,wsgiref是一個幫助開發者開發測驗的Python內置庫,程式員可以通過這個庫了解WSGI的基本運行原理,但是不能把它用在生產環境上,
二、WSGI基本原理
1. WSGI處理程序

- 瀏覽器到WSGI Server:瀏覽器發送的請求會先到WSGI Server,
- environ:WSGI Server會將HTTP請求中的引數等資訊封裝到environ(一個字典)中,
- WSGI Server到WSGI App:App就是我們自己撰寫的后臺程式,每個URL會映射到對應的入口處理函式(或其他可呼叫物件),WSGI Server呼叫后臺App時,會將environ和WSGI Server中自己的一個start_response函式注入到后臺App中,
- 邏輯處理:后臺函式(或其他可呼叫物件)需要接收environ和start_response,進行邏輯處理后回傳一個可迭代物件,可迭代物件中的元素為HTTP正文,
- WSGI App到WSGI Server:后臺函式處理完后,會先呼叫start_response函式將HTTP狀態碼、報文頭等資訊(回應頭)回傳給WSGI Server,然后再將函式的回傳值作為HTTP正文(回應body)回傳給WSGI Server,
- WSGI Server到瀏覽器:WSGI Server將從App中得到的所有資訊封裝為一個response回傳給瀏覽器,
2. WSGI示例
wsgiref簡單示例
運行以下示例程式后,在瀏覽器中輸入以http://127.0.0.1:9999/開頭的隨意一個url都可以看到回傳結果,實體程式中所有url都會以同一個App進行處理,實際生產環境中不同的url肯定是需要映射到不同的App上的,但這部分本文不作講解,
# wsgiref是Python自帶的內置庫,它用來開發者對wsgi進行測驗用的,不可以用在生產環境中
from wsgiref.simple_server import make_server, demo_app
# wsgi也是基于socket server撰寫
# 默認情況下會將所有url都傳入demo_app進行處理,具體可參考demo_app原始碼
# app引數可以是任何可呼叫物件,但是內部處理需要參考demo_app原始碼,即environ處理、start_response呼叫、回傳值型別
ws = make_server('127.0.0.1', 9999, demo_app)
# 啟動服務
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之前需要呼叫start_response設定回應頭資訊
start_response("200 OK", [('Content-Type','text/plain; charset=utf-8')])
return [stdout.getvalue().encode("utf-8")] # 一個可迭代物件,元素為byte型別,元素內容依據start_response中指定的Content-Type來指定
demo_app類定義的兩種方式
# 第一種方式:定義類的__init__和__iter__方法,前者用來接收和處理environ和start_response,后者生成一個可迭代物件
# make_server中app引數只需傳入類名即可
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引數需要傳入類的實體
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服務器和應用程式
WSGI web服務器
- 本質上是一個TCP服務器,監聽在特定的埠上,
- 支持HTTP協議,能夠決議HTTP請求報文,能夠按HTTP協議將回應資料封裝為報文并回傳給瀏覽器,
- 實作了WSGI協議,該協議約定了和應用程式之間的介面,即url到app之間的映射,
WSGI應用程式
- 遵從WSGI協議,
- 本身是一個可呼叫物件,
- 呼叫start_response,回傳回應頭部,
- 回傳包含正文的可迭代物件,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/285591.html
標籤:Python
上一篇:python基礎知識
下一篇:python從新手到安裝指南
