PEP3333指出,WSGI(Web Server Gateway Interface)是WEB服務器和web框架或web應用之間建立的一種簡單通用的接口規范。有了wsgi這份接口規范,在web開發的過程中,能更加自由的選擇服務器端和框架;在服務器端和框架的開發過程能夠分離開來,不用過多的考慮雙方具體的實現,使得服務器端和框架開發者能夠專心自己領域的開發工作。
WSGI主要由三大部分組成WSGI SERVER、WSGI Middleware 、WSGI Application,他們之間的關系是:wsgi server 接收來自客戶端的request請求,封裝environ環境變量,給app提供回調函數;調用app,並將environ和回調函數一起傳遞給app;最后接收來自app的header/status/body響應信息,傳給客戶端。wsgi Middleware是服務器和應用程序之間的橋梁,中間件同時扮演兩種角色,在服務端看來,中間是app能夠被調用,在應用程序看來,它是服務端,能夠進一步包裝需要出來的信息,並將出來的信息傳遞調用app。應用程序是我們開發程序的主體,必須可調用,必須能夠接受服務端傳過來的兩個參數environ和callback函數。將傳入進來的參數,進一步出來生成responce響應信息,傳回服務器端。下面是三者的關系圖。
實現一個服務端WSGI SERVE:
#!/usr/bin/python #coding=utf-8 def run(application): environ={} #設定環境信息 def start_response(status,headers): #define callback function pass result=application(environ,start_response) #call app pass two parameters def write(data): #訪問result iterator object pass for data in result: write(data)
從以上代碼可以看出,:server:run是服務端程序,調用可調用應用程序,app。定義一個start_response函數傳遞給app,作為回調函數。run服務端調用app后,返回一個iterator 迭代對象,將其賦值給result。write()函數在start_response將響應頭信息發送后,發送響應body信息。
Middleware
middleware 即是服務端又是應用端。那么就將滿足服務端條件:能夠配置envion,具有start_response並將其傳遞給應用程序調用應用程序;應用端條件:可調用,接收兩個參數,返回迭代對象。
def dispath(url_app_mapping): def midware_app(envion,start_responce): #callable function url=environ['PATH_INFO'] app=url_app_mapping[url] #get the view function result=app(environ, start_response) #call app return result return midware_app class dispath(): def __init__(self,application): #調用合適的app self.app=application def __call__(self,environ,start_response): #do sometiong return self.app(environ,start_response) #自身可調用
從函數的角度實現的中間件和從類的角度實現的中間件,類的角度實現的中間件更加直觀明顯。
WSGI application
#!/usr/bin/python #coding=utf-8 def app(environ,start_response): #可調用接收兩個參數 status='200 ok' headers=[('Content-type','text/plain')] #設置響應狀態碼和響應信息 start_response(status,headers) #調用回調函數 return ["hello world"] #返回body 可迭代對象
一個簡易的app應用程序,注意返回的body要是一個可迭代對象。