經過上文的討論,咱們已經對WSGI有了一點認識了,那麼如今,就讓咱們大致上認識一下Webob吧!html
WSGI是故意設計成最小的Web服務器實現輕鬆的應用,以便被更多的人採用。可是,幾乎沒有人真的喜歡直接操做
environ
變量,也幾乎沒有人喜歡用start_response
這麼詭異的邏輯,雖然WSGI提供的API易於實現,但這不表明它的語義讓人滿意。也正是由於這一緣由,幾乎每個應用程序或者web框架都把environ
和start_response
封裝成了語義更完善容錯率更高的request和response對象。Webob就是request
和response
對象的規範實現之一,它使得WSGI更容易和更滿意地被你們使用python
Webob.Request
類封裝了environ
,咱們能夠很方便的作任何事請,廢話很少,上栗子。web
from webob import Request request = Request(environ) path_info = request.path_info form_param = request.params["form_param"]
Webob.Response
類,它讓在語義上表現的更像一個HTTP
響應,它實例化出對象都是WSGI可調用的,這些實例化出來的響應對象能夠幫咱們處理start_response
這個異端,一樣,栗子。segmentfault
from webob import Response response = Response("Hello World!", "200 OK", [ ("Content-type", "text/plain"), ]) return response(environ, start_response)
看,就是這樣,依然是超輕量級,不過語義上卻更友善了。接下來,就讓咱們試試用Webob來改寫咱們以前的某個栗子吧:服務器
def __call__(self, environ, start_response): ''' WSGI entry point ''' request = Request(environ) response = self._service(request) return response(environ, start_response) def _service(self, request): assert isinstance(request, Request) path_info = request.path_info if not path_info: return request.get_response(self.application)
注意,雖然上述栗子中並無用到Response
類,可是在_service
方法中調用了get_response()
,它們是否起到了相同的做用呢?app
固然,上面的栗子只是在總體邏輯上概述了一下如何用Webob代替原生WSGI,也就是說,咱們通常在實際開發的過程當中並不這麼用,爲何(?),由於這還不夠優雅。那麼,怎麼纔算得上優雅呢?框架
對,沒錯,你可能已經猜到了,就是裝飾器。那麼,做爲獎勵,我給你個栗子:google
def wsgi_app(func): def wrapper(environ, start_response): request = Request(environ) response = func(request) return response(environ, start_response) @wsgi_app def app(resquest): body = html % (dict_to_string(request.params), dict_to_string(request.environ)) return Response(body=body, headerlist=[ ("Content-type", "text/html"), ("Content-length", str(len(body))), ])
這樣呢,之後你在想把某個app
變成WSGI的application
的時候,就能夠直接用wsgi_app
裝飾器進行裝飾就ok了,很優雅,不是嗎?設計
ps:終於要到重頭戲了,下次,咱們將開始步入 openstack 正題,來討論討論PasteDeploy
吧 :)code