什麼是WSGI

WSGI全稱爲Python Web Server Gateway Interface,Python Web服務器網關接口,它是介於Web服務器和Web應用程序(或Web框架)之間的一種簡單而通用的接口。html

咱們知道,客戶端和服務器端之間進行溝通遵循HTTP協議。可是咱們用Python所編寫的不少Web程序,並不會直接去處理HTTP請求,由於這太複雜了。因此WSGI誕生了,使從HTTP請求和Web程序之間,多了一種轉換過程——從HTTP報文轉換成WSGI的數據格式。這個時候,咱們的Web程序就能夠創建在WSGI之上,直接去處理WSGI解析給咱們的請求,而咱們就能夠專一於Web程序自己的編寫。python

一個簡單的WSGI程序

WSGI接口定義的很是簡單。根據WSGI的規定,Web程序(即WSGI程序)必須是一個可調用的對象,這個可調用對象能夠是函數、方法、類或是實現了__call__方法的類實例。這個可調用的對象接收兩個參數:web

  • environ:包含了請求的全部信息的字典。
  • start_response:須要在可調用對象中調用的函數,用來發起響應,參數是狀態碼,響應頭部等。

另外,這個可調用對象的還要返回一個可迭代的對象。shell

咱們看一個簡單的WSGI程序flask

def index(environ, start_response):
    status = '200 OK'
    response_header = [('Content-type', 'text/html')]
    start_response(status, response_header)
    yield b'<h1>Hello WSGi</h1>'

根據WSGI的定義,請求和響應的主體應爲字節串,因此咱們在這裏返回的html格式字符串上加上了b前綴將其聲明爲bytes類型瀏覽器

WSGI服務器

如今咱們的Web程序(WSGI程序)編寫好了,就須要一個WSGI服務器來運行它。Python提供了一個wsgiref庫,咱們能夠在開發時進行使用。服務器

完善上面的WSGI程序以下:app

from wsgiref.simple_server import make_server

def index(environ, start_response):
    status = '200 OK'
    response_header = [('Content-type', 'text/html')]
    start_response(status, response_header)
    yield b'<h1>Hello WSGi</h1>'

server = make_server('localhost', 5000, index)
server.serve_forever()

咱們使用make_server(host, port, application)方法建立了一個本地服務器,分別傳入主機地址、端口和可調用對象。而後使用server_forever()方法來運行它。當在shell中運行後,在瀏覽器中輸入localhost:5000就能夠看到咱們編寫的效果了。框架

WSGI服務器在啓動後會監聽本地端口,當收到請求時,他會將請求報文解析成一個environ字典,而後將其傳給WSGI程序,同時傳遞start_response函數。當咱們的WSGI程序將請求處理完後,會經過start_response方法來通知WSGI服務器來發起一個響應,並設置相應的響應頭,而後返回響應的主體。而後WSGI服務器再將其解析成HTTP格式,返回給客戶端。你也能夠經過上面的圖片來理解這個過程。函數

WSGI中間件

WSGI容許使用中間件(Middleware)來包裝Web程序,在程序在調用前添加額外的設置和屬性。這個特性經常使用來解耦程序的功能。

咱們也能夠給咱們的程序添加一箇中間件

from wsgiref.simple_server import make_server

def index(environ, start_response):
    status = '200 OK'
    response_header = [('Content-type', 'text/html')]
    start_response(status, response_header)
    yield b'<h1>Hello WSGi</h1>'

class Middleware(object):
    def __init__(self, web_app):
        self.web_app = web_app
    
    def __call__(self, environ, start_response):
        def before_start_response(status, header):
            header.append(('middleware', 'middleware'))
            return start_response(status, header)
        return self.web_app(environ, before_start_response)

new_index = Middleware(index)

server = make_server('localhost', 5000, new_index)
server.serve_forever()

這裏咱們使用實現了__call__方法的類實例來建立WSGI的可調用對象。並經過這個中間件來爲咱們的Web程序添加了一個響應頭(儘管這沒有意義)。真正的中間件遠比咱們這裏實現的複雜、功能強大的多。並且每每不止一箇中間件,而是一箇中間件堆棧,經過層層包裝,實現了很是多的功能。

Web框架

如今有了WSGI,咱們能夠很容易實現一個Python Web程序,可是這仍是不夠方便,因而有了Web框架。

Python Web框架是在WSGI的上面又抽象出來一層,使之更易使用,編寫的Python Web程序也更易維護。

咱們以很是著名的Flask框架爲例。從新實現一下上面的WSGI程序。

from flask import Flask

app = Flask(__name__)

@app.route('/')
def index():
    return '<h1>Hello WSGi</h1>'

app.run()

另外,Python還有不少流行的Web框架,例如Django,web.py、Tornado等,這裏不在詳細展開。


參考資料:

  • https://zh.wikipedia.org/wiki/Web%E6%9C%8D%E5%8A%A1%E5%99%A8%E7%BD%91%E5%85%B3%E6%8E%A5%E5%8F%A3

  • 《Flask Web開發實戰》

相關文章
相關標籤/搜索