1. 程式人生 > >[TimLinux] Python Django與WSGI的簡介

[TimLinux] Python Django與WSGI的簡介

自身 接收 需要 stat world n) super cookies sgi

1. Web應用

web應用的最原始的訪問流程:

  • 客戶端發送HTTP請求;
  • 服務端接收到請求,生成一個HTML文檔;
  • 服務端將構造HTTP響應,包含:響應頭(響應碼、鍵值對)、響應體(HTML文檔)
  • 客戶端接收HTTP響應,並呈現內容

2. WSGI

脫離底層HTTP協議層內容,只關註如何生成HTML文檔部分,並定義了一個標準:Web Server Gateway Interface。重點要求實現一個能夠接收兩個參數的可調用對象(單獨的函數,或者類中的__call__函數)

2.1. 類實現

class WSGIHandler(object):
    def __init__():
        
pass def __call__(self, environ, start_response): request = environ start_response(200 OK, [(Content-Type, text/html), ]) return Hello World app = WSGIHandler()

2.2. 函數實現

def app(environ, start_response):
    request = environ
    start_response(200 OK, [(Content-Type
, text/html),]) return Hello World

3. Http與WSGI

程序都存在輸入、輸出,WSGI定義了輸出為:響應頭和響應體,並且定義了輸入:environ和start_response,如果使用的是HTTP、NGINX等web服務器,則需要安裝對應的WSGI模塊,該模塊能夠處理WSGI標準所要求的輸入輸出。Python自身也提供了純Python實現的wsgi功能模塊:wsgiref,這個模塊會處理輸入問題,並將app返回的值最終通過HTTP發送給客戶端。示例:

from wsgiref.simple_server import make_server


def application(environ, start_response): request = environ start_response(200 OK, [(Content-Type, text/html),]) return Hello, world print("Start server: 0.0.0.0:8080") httpd = make_server(0.0.0.0, 8080, app) httpd.serve_forever()

4. Django與WSGI

web框架的核心是無法脫離WSGI的邏輯部分的,django框架的入口程序:django/core/handlers/wsgi.py#WSGIHandler.__call__函數,函數代碼(版本v1.11.6):

class WSGIHandler(base.BaseHandler):
    request_class = WSGIRequest

    def __init__(self, *args, **kwargs):
        super(WSGIHandler, self).__init__(*args, **kwargs)
        self.load_middleware()

    def __call__(self, environ, start_response):
        set_script_prefix(get_script_name(environ))
        signals.request_started.send(sender=self.__class__, environ=environ)
        request = self.request_class(environ)
        response = self.get_response(request)
response._handler_class
= self.__class__
status
= %d %s % (response.status_code, response.reason_phrase) response_headers = [(str(k), str(v)) for k, v in response.items()] for c in response.cookies.values(): response_headers.append(str(Set-Cookie), str(c.output(header=‘‘))) start_response(force_str(status), response_headers) if getattr(response, file_to_stream, None) is not None and environ.get(wsgi.file_wrapper): response = environ[wsgi.file_wrapper](response.file_to_stream) return response

[TimLinux] Python Django與WSGI的簡介