你可能想用Python來開發自己的Web應用,或者已經使用過類似于flask這樣的WSGI應用架構開發過Web應用但不知道什麼是WSGI.
這篇文章,詳細的講述到底什麼是WSGI,以及WSGI接口的簡單教程
什麼是WSGI?
當我們要用Python去開發一個Web應用時該怎麼辦?
我們要手動編寫TCP監聽,響應,發送SQL語句來與資料庫互動,生成合适的HTML。當然,這些都是在沒有輪子的情況下。
如果每一個開發人員在開發每一個Web應用時都這樣,那麼工作效率就會大大降低。是以也出現了輪子——幫忙處理TCP等繁瑣的HTTP互動,讓開發人員專注于業務邏輯代碼
是以,WSGI出現了
WSGI用于定義底層TCP的輪子與Web應用/架構之間的溝通
他們的關系是這樣的:
伺服器 => Python => WSGI Server => WSGI App/Framework => HTTP => User Request
其中:
WSGI Server : 負責TCP等方面的業務
WSGI App/Framework : 負責通過WSGI與WSGI Server溝通,處理業務邏輯代碼
而WSGI接口就是用來連接配接這兩個子產品的。WSGI Server通過接口把HTTP的請求資訊傳給WSGI App/Framework,而WSGI App/Framework通過接口把HTTP的響應資訊傳給WSGI Server .
一個小示例
WSGI的接口簡直棒極了,因為十分的簡單。Python自帶了一個WSGI Server叫wsgiref,而WSGI App/Framework可以隻是一個函數,我們讓wsgiref來調用這個函數
WSGI App/Framework :
def wsgi_app(self, environ, start_response):
start_response("200 OK",[])
return ["hello world".encode("utf-8")]
environ和start_response都是由WSGI Server傳給我們的,我們可以把他通俗的叫做上下文,因為它包括了每一次HTTP請求的資訊。WSGI Server每接到一次請求,接調用這個函數一次
start_response接受倆參數,一個是HTTP狀态碼;一個是由清單組成的HTTP Headers ; 狀态碼必須是至少有四個字元的字元串,我在菜鳥教程上整理了一下:
{
100:"Continue",
101:"Switching Protocols",
200:"OK",
201:"Created",
202:"Accepted",
203:"Non-Authoritative Information",
204:"No Content",
205:"Reset Content",
206:"Partial Content",
300:"Multiple Choices",
301:"Moved Permanently",
302:"Found",
303:"See Other",
304:"Not Modified",
305:"Use Proxy",
306:"Unused",
307:"Temporary Redirect",
400:"Bad Request",
401:"Unauthorized",
402:"Payment Required",
403:"Forbidden",
404:"Not Found",
405:"Method Not Allowed",
406:"Not Acceptable",
407:"Proxy Authentication Required",
408:"Request Time-out",
409:"Conflict",
410:"Gone",
411:"Length Required",
412:"Precondition Failed",
413:"Request Entity Too Large",
414:"Request-URI Too Large",
415:"Unsupported Media Type",
416:"Requested range not satisfiable",
417:"Expectation Failed",
500:"Internal Server Error",
501:"Not Implemented",
502:"Bad Gateway",
503:"Service Unavailable",
504:"Gateway Time-out",
505:"HTTP Version not supported"
}
WSGI Server :
from wsgiref.simple_server import make_server
httpd = make_server("", port, wsgi_app)
print("Server Running at http://127.0.0.1:{}".format(port) + "/")
httpd.serve_forever()
我們導入wsgiref,建立httpd對象并傳入我們的WSGI App/Framework函數,列印運作日志,并在端口上監聽響應。因為每一個WSGI Server的參數都不一樣,是以這裡不多做介紹,請自行百度。
嘗試通路下:
$ python server.py
Server Running at http://127.0.0.1:8080/
127.0.0.1 - - [20/Oct/2020 21:47:18] "GET / HTTP/1.1" 200 16
成功響應
調用environ參數
我們可以通過WSGI Server傳入的environ參數來擷取HTTP請求的資訊,environ參數大緻上是一個字典,擷取資訊大緻這樣:
# 擷取HTTP請求的請求方式:GET or POST
environ["REQUEST_METHOD"]
# 擷取HTTP請求的路徑: /request_url
environ["PATH_INFO"]
有關于更多的資訊,請參考 PEP 0333
start_response函數
我們可以通過WSGI Server傳入的start_response函數來設定我們傳回的HTTP資訊,這裡是不錯的一些例子:
# 設定HTTP響應碼: 200 OK
start_response("200 OK",[])
# 設定HTTP響應頭: ("content_type","text/html")
start_response("200 Ok",[("content_type","text/html"),]
需要注意的是,start_response函數隻能調用一次,上面的示例需要合并。有關于HTTP響應頭的疑問,可以參考 HTTP響應頭資訊
寫在最後
以上就是WSGI的基本介紹,如果想更深入的了解WSGI,還是請閱讀官方文檔吧。
09後第一次寫文章,不喜勿噴