WebOb

WebOb
  WebOb是一个封装了WSGI的请求和应答的Python库。
  WebOb是WSGI(Web Server Gateway Interface) request and response objects的缩写。WebOb提供了多个对象,这些对象大部分都用来处理HTTP的行为,包括对HTTP头的解析,内容的处理,创建WSGI的应答(包括HTTP的状态、头和body)等等。WebOb可以帮助开发者开发丰富的应用和中间件,而不需要知道WSGI和HTTP的复杂细节。
  WebOb的优势:
1.将大部分的HTTP特性映射到友好的数据结构
2.代码经过时间的检验,并且隐藏了WSGI怪异的细节
3.已知零问题,如果有问题上报,会尽快处理
4.100%的测试覆盖率
5.不依赖于其它扩展库
6.支持Python3

  使用WebOb的著名框架和网站有:
1.Pyramid
2.Pylons web framework
3.TurboGears
4.Google App Engine
5.OpenStack (Rackspace CloudFiles)
6.Restish, Bobo, webapp2
7.Reddit, Sourceforge, SurveyMonkey, Dropbox, bittorrent.com, Freshbooks, Freebase, Digg等等

webob.Request和webob.Response

  WebOb最重要的两个类是Request和Response,Request主要用来构造和解析HTTP请求,而Response主要是用来构造HTTP的应答。为了循序渐进的理解Request和Response的作用,我们先理解一下WSGI的application。一个符合WSGI的application是一个可调用对象,最简单的是一个函数,下面是一个简单的例子:

from wsgiref.simple_server import make_server

def app(environ, start_response):
    start_response('200 OK', [('Content-Type', 'text/html')])
    content = []
    content.append('This my app.')
    for key, value in environ.items():
        content.append('%s: %s' % (key, value))
    body = ['\n'.join(content).encode('utf-8')]

    return body

if __name__ == '__main__':
    port = 8000
    server = make_server('', port, app)
    print('Serving HTTP on port %s ...' % port)
    server.serve_forever()

  使用curl可以向服务端发送请求:

[root@controller workspace]# curl http://127.0.0.1:8000
This my app.
[root@controller workspace]# curl http://127.0.0.1:8000
This my app.
SERVER_SOFTWARE: WSGIServer/0.1 Python/2.7.5
SCRIPT_NAME:
REQUEST_METHOD: GET
SERVER_PROTOCOL: HTTP/1.1
...

  使用WebOb的Request和Response可以封装对environ和响应的处理,简化了程序,使其代码更加清晰。下面是一个简单的例子:

from wsgiref.simple_server import make_server
from webob import Request, Response

def app(environ, start_response):
    request = Request(environ)

    content = []
    content.append('This my app.')
    for key, value in environ.items():
        content.append('%s: %s' % (key, value))

    response = Response(body='\n'.join(content))
    response.headers['content-type'] = 'text/plain'

    return response(environ, start_response)

if __name__ == '__main__':
    port = 8000
    server = make_server('', port, app)
    print('Serving HTTP on port %s ...' % port)
    server.serve_forever()

  使用curl命令,可以发现其输出内容与上一个程序相同:

[root@controller workspace]# curl http://127.0.0.1:8000
This my app.
[root@controller workspace]# curl http://127.0.0.1:8000
This my app.
SERVER_SOFTWARE: WSGIServer/0.1 Python/2.7.5
SCRIPT_NAME:
REQUEST_METHOD: GET
SERVER_PROTOCOL: HTTP/1.1
...


webob.dec

  WebOb还包括一个重要的装饰器——wsgify,它屏蔽了WSGI对application要求的细节,使开发者可以专注于实际业务的开发。使用wsgify后,开发者只需要提供一个可调用对象(函数是最简单的可调用对象),可调用对象接受一个Request的实例,并返回一个Response的实例即可。下面是一个使用wsgify的简单例子:

from wsgiref.simple_server import make_server
from webob import Request, Response
from webob.dec import wsgify

@wsgify
def app(request):
    content = []
    content.append('This my app.')
    for key, value in request.environ.items():
        content.append('%s: %s' % (key, value))

    response = Response(body='\n'.join(content))
    response.headers['content-type'] = 'text/plain'

    return response

if __name__ == '__main__':
    port = 8000
    server = make_server('', port, app)
    print('Serving HTTP on port %s ...' % port)
    server.serve_forever()

  使用curl命令,可以发现其输出内容与上一个程序相同:

[root@controller workspace]# curl http://127.0.0.1:8000
This my app.
[root@controller workspace]# curl http://127.0.0.1:8000
This my app.
SERVER_SOFTWARE: WSGIServer/0.1 Python/2.7.5
SCRIPT_NAME:
REQUEST_METHOD: GET
SERVER_PROTOCOL: HTTP/1.1
...

参考资料:
  webob