Flask前言 - Python WSGI

所有的Python web框架都需要WSGI協(xié)議,所以要深入了解一個web框架,很有必要去了解下WSGI;

WSGI(Web Server Gateway Interface) 的任務(wù)就是把上面的數(shù)據(jù)在 http server 和 python 程序之間簡單友好地傳遞。它是一個標(biāo)準(zhǔn),被定義在PEP 333。需要 http server 和 python 程序都要遵守一定的規(guī)范,實現(xiàn)這個標(biāo)準(zhǔn)的約定內(nèi)容,才能正常工作。

image
image

圖片出處

WSGI Application端

application端定義非常簡單,它只要求開發(fā)者實現(xiàn)一個函數(shù)來響應(yīng)HTTP請求。

這個函數(shù)就是一個符合WSGI標(biāo)準(zhǔn)的一個HTTP處理函數(shù),它接收兩個參數(shù):

  • environ: 一個包含所有HTTP請求信息的dict對象。
  • start_response: 一個發(fā)送HTTP響應(yīng)的函數(shù),這個函數(shù)接受兩個參數(shù),一個是HTTP響應(yīng)碼,一個是HTTP header。
# wsgi_client.py

def application(environ, start_response):
    start_response('200 OK', [('Content-Type', 'text/html')])
    return ["hello world"]

WSGI Server端

envrionstart_response這兩個參數(shù)由服務(wù)端提供,PEP333里給出了一個wsgi server的簡單實現(xiàn):

import os, sys

def run_with_cgi(application):    # application 是程序端的可調(diào)用對象
    # 準(zhǔn)備 environ 參數(shù),這是一個字典,里面的內(nèi)容是一次 HTTP 請求的環(huán)境變量
    environ = dict(os.environ.items())
    environ['wsgi.input']        = sys.stdin
    environ['wsgi.errors']       = sys.stderr
    environ['wsgi.version']      = (1, 0)
    environ['wsgi.multithread']  = False
    environ['wsgi.multiprocess'] = True
    environ['wsgi.run_once']     = True         
    environ['wsgi.url_scheme'] = 'http'

    headers_set = []
    headers_sent = []

    # 把應(yīng)答的結(jié)果輸出到終端
    def write(data):
        sys.stdout.write(data)
        sys.stdout.flush()

    # 實現(xiàn) start_response 函數(shù),根據(jù)程序端傳過來的 status 和 response_headers 參數(shù),
    # 設(shè)置狀態(tài)和頭部
    def start_response(status, response_headers, exc_info=None):
        headers_set[:] = [status, response_headers]
        return write

    # 調(diào)用客戶端的可調(diào)用對象,把準(zhǔn)備好的參數(shù)傳遞過去
    result = application(environ, start_response)
    
    # 處理得到的結(jié)果,這里簡單地把結(jié)果輸出到標(biāo)準(zhǔn)輸出。
    try:
        for data in result:
            if data:    # don't send headers until body appears
                write(data)
    finally:
        if hasattr(result, 'close'):
            result.close()

或者,python中也內(nèi)置了一個WSGI服務(wù)器模塊wsgiref, 通過這個模塊就可以快速實現(xiàn)了個WSGI Server來測試我們的application:

# wsgi_server.py
# 從wsgiref模塊導(dǎo)入:
from wsgiref.simple_server import make_server
# 導(dǎo)入我們自己編寫的application函數(shù):
import wsgi_client

# 創(chuàng)建一個服務(wù)器,IP地址為空,端口是8000,處理函數(shù)是application:
httpd = make_server('', 8000, wsgi_client.application)
print('Serving HTTP on port 8000...')
# 開始監(jiān)聽HTTP請求:
httpd.serve_forever()

可以看到結(jié)果為wsgi_client.py中定義的hello world

200ok.png

Flask框架中的一個核心庫werkzeug其實就是Python的WSGI規(guī)范的實用函數(shù)庫

參考

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,545評論 19 139
  • # Python 資源大全中文版 我想很多程序員應(yīng)該記得 GitHub 上有一個 Awesome - XXX 系列...
    aimaile閱讀 26,832評論 6 427
  • 一、Web開發(fā) Browser/Server模式目前最流行,簡稱BS架構(gòu)。在BS架構(gòu)下,客戶端只需要瀏覽器,應(yīng)用程...
    時間之友閱讀 913評論 0 0
  • 今年,距離我們分開已經(jīng)六年了,也是我喜歡你的第八個春秋。我不知道自己還能擁有這種感覺多久,自從高中畢業(yè)后,我花...
    by追憶冰藍(lán)閱讀 452評論 0 1
  • 胡楊在大漠里說著古老的歷史 一頭北極熊望著冰山,它的家園 颶風(fēng)好奇的登上陸地打量一切 南半球一個孩子燈光下安靜作畫...
    封城雪閱讀 139評論 0 5

友情鏈接更多精彩內(nèi)容