Python Web開發:從 wsgi 開始

年薪四千萬日元的長江發表於2019-05-01

本文參考了:

想要理解wsgi,首先得區分一個概念:server 和 app。

此圖來源於:www.toptal.com/python/pyth…

Python Web開發:從 wsgi 開始

uwsgi、gunicorn是 server,我們寫的 django、flask、sanic 程式是 app。app 就是一個可被呼叫的物件(callable object),server 會解析請求資料傳給 app,app 執行業務邏輯之後,把結果返回給 server。

現實生活中,我們部署的時候,可能還會在 server 前面加上一個 nginx,所以整個流程簡單來說是這樣的:

Python Web開發:從 wsgi 開始

app 可巢狀 -> 中介軟體

app 是一個可呼叫物件,這意味著我可以在 app1裡面呼叫 app2,app2裡面再呼叫 app3,這樣一層一層巢狀下去。這不就是 middleware 嗎?

Python Web開發:從 wsgi 開始

如果你看過 django middleware 的原始碼,會看到MiddlewareMixin這個類:

class MiddlewareMixin:
    def __init__(self, get_response=None):
        self.get_response = get_response
        super().__init__()

    def __call__(self, request):
        response = None
        if hasattr(self, 'process_request'):
            response = self.process_request(request)
        response = response or self.get_response(request)
        if hasattr(self, 'process_response'):
            response = self.process_response(request, response)
        return response
複製程式碼

定義了一個__call__方法,它是一個可呼叫物件。

你在 django 配置檔案中定義的:

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
複製程式碼

執行的時候,就是這樣一個一個地呼叫 middleware,直到呼叫到你的業務邏輯程式碼(最終的 app 部分)。

後面會再詳細講講中介軟體開發。

app向server暴露的介面

app 是一個可呼叫的物件,它需要接收一些引數,具體如下:

def app(environ,start_response):
    pass
複製程式碼

具體看一下這兩個引數:

  • environ,就是一個保護請求資訊的字典。

比如 server 收到GET http://localhost:8000/auth?user=obiwan&token=123這條請求後,會生成下面這樣一個 environ 字典:

Python Web開發:從 wsgi 開始

這裡麵包含了此次請求的所有必要資訊,通過這個字典,app就能知道這次請求的 path 是/auth,於是就知道該呼叫哪個 handler 函式。還能通過 HTTP_COOKIE知道 cookie 值,然後可以定位到具體的使用者。

  • start_response(status, headers,errors)

Server 傳給 app 的回撥函式,返回資料給 server 之前需要先呼叫這個回撥函式,通知 server 你該來獲取返回資料了。

聽說這個引數實已經快有被廢棄了,不需要完全瞭解。下圖來源於:WSGI: The Server-Application Interface for Python底部評論區。

Python Web開發:從 wsgi 開始

Python Web開發:從 wsgi 開始

如果你像我一樣真正熱愛電腦科學,喜歡研究底層邏輯,歡迎關注我的微信公眾號:

Python Web開發:從 wsgi 開始

相關文章