前言
本文主要介紹的是Python WSGI相關內容,主要來自以下網址:
What is WSGI? WSGI Tutorial An Introduction to the Python Web Server Gateway Interface (WSGI)可以看成一次簡單粗暴的翻譯。
什么是WSGI
WSGI的全稱是Web Server Gateway Interface,這是一個規范,描述了web server如何與web application交互、web application如何處理請求。該規范的具體描述在PEP 3333。注意,WSGI既要實現web server,也要實現web application。
實現了WSGI的模塊/庫有wsgiref(python內置)、werkzeug.serving、twisted.web等,具體可見Servers which support WSGI。
當前運行在WSGI之上的web框架有Bottle、Flask、Django等,具體可見Frameworks that run on WSGI。
WSGI server所做的工作僅僅是將從客戶端收到的請求傳遞給WSGI application,然后將WSGI application的返回值作為響應傳給客戶端。WSGI applications 可以是棧式的,這個棧的中間部分叫做中間件,兩端是必須要實現的application和server。
WSGI教程
這部分內容主要來自WSGI Tutorial。
WSGI application接口
WSGI application接口應該實現為一個可調用對象,例如函數、方法、類、含__call__方法的實例。這個可調用對象可以接收2個參數:
一個字典,該字典可以包含了客戶端請求的信息以及其他信息,可以認為是請求上下文,一般叫做environment(編碼中多簡寫為environ、env); 一個用于發送HTTP響應狀態(HTTP status )、響應頭(HTTP headers)的回調函數。同時,可調用對象的返回值是響應正文(response body),響應正文是可迭代的、并包含了多個字符串。
WSGI application結構如下:
def application (environ, start_response): response_body = 'Request method: %s' % environ['REQUEST_METHOD'] # HTTP響應狀態 status = '200 OK' # HTTP響應頭,注意格式 response_headers = [ ('Content-Type', 'text/plain'), ('Content-Length', str(len(response_body))) ] # 將響應狀態和響應頭交給WSGI server start_response(status, response_headers) # 返回響應正文 return [response_body]
Environment
下面的程序可以將environment字典的內容返回給客戶端(environment.py):
# ! /usr/bin/env python# -*- coding: utf-8 -*- # 導入python內置的WSGI serverfrom wsgiref.simple_server import make_serverdef application (environ, start_response): response_body = [ '%s: %s' % (key, value) for key, value in sorted(environ.items()) ] response_body = '/n'.join(response_body) # 由于下面將Content-Type設置為text/plain,所以`/n`在瀏覽器中會起到換行的作用 status = '200 OK' response_headers = [ ('Content-Type', 'text/plain'), ('Content-Length', str(len(response_body))) ] start_response(status, response_headers) return [response_body]# 實例化WSGI serverhttpd = make_server ( '127.0.0.1', 8051, # port application # WSGI application,此處就是一個函數)# handle_request函數只能處理一次請求,之后就在控制臺`print 'end'`了httpd.handle_request()print 'end'
新聞熱點
疑難解答