Webob——WSGI的“滤镜”

通过上文的讨论,我们已经对WSGI有了一点认识了,那么现在,就让我们大体上认识一下Webob吧!

什么是Webob?


WSGI是故意设计成最小的Web服务器实现轻松的应用,以便被更多的人采用。但是,几乎没有人真的喜欢直接操作environ变量,也几乎没有人喜欢用start_response这么诡异的逻辑,虽然WSGI提供的API易于实现,但这不代表它的语义让人满意。也正是因为这一原因,几乎每一个应用程序或者web框架都把environstart_response封装成了语义更完善容错率更高的request和response对象。Webob就是requestresponse对象的规范实现之一,它使得WSGI更容易和更满意地被大家使用

Webob: request & response 对象


Webob.Request类封装了environ,我们可以很方便的做任何事请,废话不多,上栗子。

from webob import Request
request = Request(environ)
path_info = request.path_info
form_param = request.params["form_param"]

Webob.Response类,它让在语义上表现的更像一个HTTP响应,它实例化出对象都是WSGI可调用的,这些实例化出来的响应对象可以帮我们处理start_response这个异端,同样,栗子。

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()它们是否起到了相同的作用呢

当然,上面的栗子只是在整体逻辑上概述了一下如何用Webob代替原生WSGI,也就是说,我们一般在实际开发的过程中并不这么用,为什么(?),因为这还不够优雅。那么,怎么才算得上优雅呢?

使用装饰器模式通过Webob封装WSGI入口

对,没错,你可能已经猜到了,就是装饰器。那么,作为奖励,我给你个栗子:

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吧 :)

你可能感兴趣的:(wsgi,openstack,webob)