一、WSGI為什么會出現?
在學習一個東西之前,我們肯定想知道:它為什么會出現?那么,WSGI為什么會出現呢?
我們知道,部署一個web應用,經常需要使用nginx、apache或者IIS等web服務器把web應用跑起來,然后用戶在瀏覽器可以通過URL進行訪問。
為了能夠讓各種web服務器都能支持web應用,所以必須在web應用和web服務器之間有一個統一的規范(協議)。
其實,在PEP 3333中也有提到它的目標:
為了定義了一個“ Web 服務器和 Python Web 應用程序或框架之間”的標准接口,以便提升 Web 應用程序在不同 Web 服務器上的可移植性。
注意:
1、這里的web應用是Python Web應用程序。
2、這里的web服務器是指nginx、apache等。
3、WSGI為什么會出現在WSGI有更加詳細的說明。
https://github.com/python/peps/blob/master/pep-0333.txt
二、什么是WSGI?
WSGI,全稱 Web Server Gateway Interface,或者 Python Web Server Gateway Interface ,是為 Python 語言定義的 Web 服務器和 Web 應用程序或框架之間的一種簡單而通用的接口。
更精確的說,應該是一種協議或規范:描述web server
如何與web application
通信的規范。server
和application
的規范在PEP 3333中有具體描述。要實現WSGI協議,必須同時實現web server和web application,當前運行在WSGI
協議之上的web
框架有Bottle
, Flask
, Django
。
它是一個標准,描述了一個web server和web app如何通訊,以及webapp怎么處理前端請求。一個web服務流程類似於這樣:
WSGI的主要作用是在Web服務器(uwsgi)和Web應用程序(application)承擔“翻譯官”的角色。對於這一角色可以這樣理解:
- Web服務器的責任在於監聽和接收請求。在處理請求的時候調用WSGI提供的標准化接口,將請求的信息轉給WSGI;
- WSGI的責任在於“中轉”請求和響應信息。WSGI接收到Web服務器提供的請求信息后可以做一些處理,之后通過標准化接口調用Web應用,並將請求信息傳遞給Web應用。同時,WSGI還將會處理Web應用返回的響應信息,並通過服務器返回給客戶端;
- Web應用的責任在於接收請求信息,並且生成響應。
根據以上分析,要實現符合WSGI標准的Web服務,服務器和應用程序的設計就要符合WSGI規范。
這里引申出一個概念:uwsgi
uwsgi定義:與WSGI
一樣,是一種通信協議,是uWSGI
服務器的獨立協議。是一個web
服務器,實現了WSGI
協議、uwsgi
協議、http
協議等。
用於定義傳輸信息的類型(type of information
),每一個uwsgi packet
前4byte
為傳輸信息類型的描述,與WSGI協議是兩個不同的協議,據說該協議是fcgi
協議的10倍快。
三、WSGI實現
因為WSGI其實就是一個協議,根據官方的定義,大致內容如下:
● WSGI application能夠調用python對象(函數或者一個帶有__call__方法的類。__call__方法有2個參數:第一個參數是WSGI的environ,第二個參數是一個start_response函數。
● application必須使用start_response(status,headers),並且返回值是一個可迭的代序列,序列中的每個對象將標准輸出。
● WSGI environ和CGI environ一樣,都是一些鍵值對,要么是提供給server,要么提供給middleware。
● 可以將包裝后的middleware添加到你的app中。
下面是一個簡單的例子:
def application(env, start_response):
start_response('200 OK', [('Content-Type', 'text/html')])
return '<h1>Hello, web!</h1>'
作為web app本身,你就算啟動了程序,你也沒辦法給application傳遞參數。
所以,實際上,調用application和傳遞2個參數的動作,是web 服務器來進行的,比如uwsgi.
而這個叫做application的東西,在Flask框架內部的名字,叫做wsgi_app。
四、Werkzeug
Werkzeug是什么鬼呢?Werkzeug是一個WSGI工具包,他可以作為一個Web框架的底層庫。Flask就用到了這個庫。Flask主要用到了Werkzeug和jinja2兩個庫。
Werkzeug官方文檔說明如下:
werkzeug ~~~~~~~~ Werkzeug is the Swiss Army knife of Python web development. Werkzeug是python web開發的一把瑞士軍刀。 It provides useful classes and functions for any WSGI application to make the life of a python web developer much easier. All of the provided classes are independent from each other so you can mix it with any other library. 它為WSGI應用提供了有用的類和函數,讓python的web開發工作更容易。Werkeug提供的所有類都是彼此解耦的,所以你能夠使用其他任何庫進行糅雜。 (翻譯不是非常到位,哈哈)
五、結束語
最后以 Nginx(web server),WSGI,Flask(web app) 之間的對話結束本文。
===========================================================
Nginx:Hey,WSGI,我剛從用戶那里收到了一個請求,現在轉發給你。
WSGI:好的,Nginx,我會設置好環境變量,然后將這個請求傳遞給Flask處理。
Flask:Thanks WSGI!給我一些時間,我將會把請求的響應返回給你。
WSGI:All right,那我等你。
Flask:Okay,我完成了,這里是請求的響應結果,請求把結果傳遞給Nginx。
WSGI:Good job!Nginx,這里是響應結果,已經按照要求給你傳遞回來了。
Nginx:Cool,我收到了,我把響應結果返回給客戶端。大家合作愉快~