WebOb的简单介绍

在之前的文章中我写了有关于如何使用PasteDeploy生成WSGI的Application。在Openstack的源码中,除了 PasteDeploy外,还有一个和WSGI密切相关的工具包WebOb。这篇文章就来讲讲这个WebOb。官网在 这:http://webob.org/

简单的说,WebOb是一个用于对WSGI request环境进行包装(也就是变得易用)以及用于创建WSGI response的一个包。

1.Request
webob.Request是WebOb中的一个重要对象。其会的对WSGI的environ(就是传递给WSGI APP的那个参数)参数进行封装。
一个简单的例子:


1

2

3

4

5

from webob import Request

req = Request.blank(‘/article?id=1‘)

from pprint import pprint

pprint(req.environ)

输出:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

[[email protected]_DEV dev]# python webobtest.py

{‘HTTP_HOST‘: ‘localhost:80‘,

 ‘PATH_INFO‘: ‘/article‘,

 ‘QUERY_STRING‘: ‘id=1‘,

 ‘REQUEST_METHOD‘: ‘GET‘,

 ‘SCRIPT_NAME‘: ‘‘,

 ‘SERVER_NAME‘: ‘localhost‘,

 ‘SERVER_PORT‘: ‘80‘,

 ‘SERVER_PROTOCOL‘: ‘HTTP/1.0‘,

 ‘wsgi.errors‘: <open file ‘<stderr>‘, mode ‘w‘ at 0x7f83c59d21e0>,

 ‘wsgi.input‘: <io.BytesIO object at 0x7f83c592b590>,

 ‘wsgi.multiprocess‘: False,

 ‘wsgi.multithread‘: False,

 ‘wsgi.run_once‘: False,

 ‘wsgi.url_scheme‘: ‘http‘,

 ‘wsgi.version‘: (1, 0)}

既然是request,那么必然有个body,并且也有request的方法(GET?POST?DELETE?),所以文档里有这么个例子:


1

2

3

4

5

6

7

8

9

10

>>> hasattr(req.body_file, ‘read‘)

True

>>> req.body

‘‘

>>> req.method = ‘PUT‘

>>> req.body = ‘test‘

>>> hasattr(req.body_file, ‘read‘)

True

>>> req.body

‘test‘

对request请求头部的操作如下:


1

2

3

4

5

>>> req.headers[‘Content-Type‘] = ‘application/x-www-urlencoded‘

>>> sorted(req.headers.items())

[(‘Content-Length‘, ‘4‘), (‘Content-Type‘, ‘application/x-www-urlencoded‘), (‘Host‘, ‘localhost:80‘)]

>>> req.environ[‘CONTENT_TYPE‘]

‘application/x-www-urlencoded‘

对请求参数的处理如下:


1

2

3

4

5

6

7

8

9

>>> req = Request.blank(‘/test?check=a&check=b&name=Bob‘)

>>> req.GET

MultiDict([(u‘check‘, u‘a‘), (u‘check‘, u‘b‘), (u‘name‘, u‘Bob‘)])

>>> req.GET[‘check‘]

u‘b‘

>>> req.GET.getall(‘check‘)

[u‘a‘, u‘b‘]

>>> req.GET.items()

[(u‘check‘, u‘a‘), (u‘check‘, u‘b‘), (u‘name‘, u‘Bob‘)]

下面这个是比较常见的查看参数的方法:


1

2

3

4

5

6

7

8

9

10

11

12

13

>>> req.params

NestedMultiDict([(u‘check‘, u‘a‘), (u‘check‘, u‘b‘), (u‘name‘, u‘Bob‘), (u‘name‘, u‘Joe‘), (u‘email‘, u‘[email protected]‘)])

>>> req.params[‘name‘]

u‘Bob‘

>>> req.params.getall(‘name‘)

[u‘Bob‘, u‘Joe‘]

>>> for name, value in req.params.items():

...     print ‘%s: %r‘ % (name, value)

check: u‘a‘

check: u‘b‘

name: u‘Bob‘

name: u‘Joe‘

email: u‘[email protected]‘

一个把request传递给WSGI应用的例子:


1

2

3

4

5

6

7

8

9

from webob import Request

req = Request.blank(‘/‘)

def wsgi_app(environ, start_response):

    start_response(‘200 OK‘, [(‘Content-type‘, ‘text/plain‘)])

    return [‘Hi!‘]

print req.call_application(wsgi_app)

输出:


1

2

[[email protected]_DEV dev]# python webobtest.py

(‘200 OK‘, [(‘Content-type‘, ‘text/plain‘)], [‘Hi!‘])

2.Response
webob.Response包含了标准WSGI response的所有要素。其本身也可以看成是一个WSGI的application。你可以通过req.call_application(res)对其调用。

最简单的例子如下:


1

2

3

4

5

6

7

8

>>> from webob import Response

>>> res = Response()

>>> res.status

‘200 OK‘

>>> res.headerlist

[(‘Content-Type‘, ‘text/html; charset=UTF-8‘), (‘Content-Length‘, ‘0‘)]

>>> res.body

‘‘

如何写入body:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

>>> res = Response(content_type=‘text/plain‘, charset=None)

>>> f = res.body_file

>>> f.write(‘hey‘)

>>> f.write(u‘test‘)

Traceback (most recent call last):

  . . .

TypeError: You can only write unicode to Response if charset has been set

>>> f.encoding

>>> res.charset = ‘utf8‘

>>> f.encoding

‘utf8‘

>>> f.write(u‘test‘)

>>> res.app_iter

[‘‘, ‘hey‘, ‘test‘]

>>> res.body

‘heytest‘

注意下这个例子,这个例子把普通的WSGI的应用通过Request和Response做了一个简单的包装,虽然没有太大的修改,但对于之后使用装饰器的情况来说,是个不错的例子:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

>>> def my_app(environ, start_response):

...     req = Request(environ)

...     res = Response()

...     res.content_type = ‘text/plain‘

...     parts = []

...     for name, value in sorted(req.environ.items()):

...         parts.append(‘%s: %r‘ % (name, value))

...     res.body = ‘n‘.join(parts)

...     return res(environ, start_response)

>>> req = Request.blank(‘/‘)

>>> res = req.get_response(my_app)

>>> print res

200 OK

Content-Type: text/plain; charset=UTF-8

Content-Length: ...

HTTP_HOST: ‘localhost:80‘

PATH_INFO: ‘/‘

QUERY_STRING: ‘‘

REQUEST_METHOD: ‘GET‘

SCRIPT_NAME: ‘‘

SERVER_NAME: ‘localhost‘

SERVER_PORT: ‘80‘

SERVER_PROTOCOL: ‘HTTP/1.0‘

wsgi.errors: <open file ‘<stderr>‘, mode ‘w‘ at ...>

wsgi.input: <...IO... object at ...>

wsgi.multiprocess: False

wsgi.multithread: False

wsgi.run_once: False

wsgi.url_scheme: ‘http‘

wsgi.version: (1, 0)

3.Exceptions
其实就是对HTTP错误代码的一个封装。也可以看成是一个WSGI的应用。

一个简单的例子:


1

2

3

4

5

6

7

8

9

10

11

12

>>> from webob.exc import *

>>> exc = HTTPTemporaryRedirect(location=‘foo‘)

>>> req = Request.blank(‘/path/to/something‘)

>>> print str(req.get_response(exc)).strip()

307 Temporary Redirect

Location: http://localhost/path/to/foo

Content-Length: 126

Content-Type: text/plain; charset=UTF-8

307 Temporary Redirect

The resource has been moved to http://localhost/path/to/foo; you should be redirected automatically.

4. WSGIfy decorator
结合上面的例子,既然WebOb可以让WSGI的请求变得更加简单、强大,那么能不能不用原始的那种WSGI的参数和返回格式,而全部用WebOb替代?可以的,通过WSGIfy decorator这个装饰器。

比如这个最简单的例子:


1

2

3

@wsgify

def myfunc(req):

    return webob.Response(‘hey there‘)

调用的时候有两个选择:


1

app_iter = myfunc(environ, start_response)

或:


1

resp = myfunc(req)

第一种选择就是最原始和标准的的WSGI格式,第二种选择则是WebOb封装过后的格式。说实话后者看上去更加符合逻辑(给你个请求,给我个响应)。

如果myfanc直接返回一个Exception,那么就会的相当于直接调用Exception这个WebOb的WSGI Application,可以很容易的返回异常页面。

另外也可以对Request进行继承,修改其内容,对真正的Request做一些判断(个人感觉像是在过滤),比如:


1

2

3

4

5

6

7

8

9

10

class MyRequest(webob.Request):

    @property

    def is_local(self):

        return self.remote_addr == ‘127.0.0.1‘

@wsgify(RequestClass=MyRequest)

def myfunc(req):

    if req.is_local:

        return Response(‘hi!‘)

    else:

        raise webob.exc.HTTPForbidden

需要记住一点:被@wsgify修饰过后的那些func,其Return的是个对Response的调用。

5.总结
总结一下WebOb。既然有人用WebOb,那它必然有它的好用的地方,好用的地方在哪里呢?我个人觉得有两个:一是兼容性好,二是使用简单。
首先先说兼容性吧。之前写过文章介绍过PasteDeploy,后者可以通过标准的配置文件生成WSGI应用。那么通过WebOb写出的WSGI应用是否
可以用在这里呢?答案是可以的,上面的装饰器的例子已经介绍了,经过装饰器装饰后的func可以通过标准的WSGI方法去调用。
然后说说使用上的感觉。简单就是好用。其把WSGI的几个参数、返回的方法都封装成了Reqeust、Response这两个对象,同时还提供了一个好用的Exception对象,就这三个对象,记起来也不难,读起来也一看就知道是啥意思,所以说用起来方便。

个人觉得最有代表的例子是这个,一目了然,使人一读就懂。最神奇的是可以通过WSGI标准对其进行调用,写的时候完全可以忘了WSGI标准是啥,同时还能写出兼容WSGI工具(比如PasteDeploy)的代码,真是不错。


1

2

3

@wsgify

def myfunc(req):

    return webob.Response(‘hey there‘)

时间: 2024-10-13 06:55:15

WebOb的简单介绍的相关文章

python的列表,元组和字典简单介绍

引 入 java                                   python 存取多个值:数组或list集合 ------------------------> 列表,元组 key-value格式:    Map        ------------------------>    字典 自己学习发现,java跟python这两门面向对象语言在数据类型的定义上,很多思想都是互通的,这里不说java,简单介绍一下python的列表,元组和字典. 一.列表 List: 最通

javascript的return语句简单介绍

javascript的return语句简单介绍:return语句在js中非常的重要,不仅仅具有返回函数值的功能,还具有一些特殊的用法,有个清晰的把握是非常有必要的.下面就结合实例简单介绍一下return语句的作用.一.用来返回控制和函数结果:通常情况,return语句对于一个函数是很有必要的,因为往往需要函数在一系列的代码执行后会得到一个期望的返回值,而此值就是通过return语句返回,并且将控制权返回给主调函数.语法格式: return 表达式 代码实例如下: function add(){

Object-c集合的简单介绍

一.简单介绍 NSArray/NSMutableArray NSSet/NSMutableSet NSDictionary/NSMutableDictionary NSArray.NSSet.NSDictionary是不可变的,创建的时候初始化 NSMutableArray.NSMutableSet.NSMutableDictionary是可变的 二.使用介绍 NSArray是有序的数组 NSMutableArray *myArray=[[NSMutableArray alloc] init];

plsql的环境与介绍:环境的搭建和plsql的简单介绍

PLSQL编程 1.环境的搭建 (1)创建一个存储表空间 SQL> conn /as sysdbaConnected. SQL> create tablespace plsql datafile '/u01/oracle/oradata/ORCL/plsql01.dbf' size 1G; Tablespace created. (2)创建PLSQL用户SQL> create user plsql identified by plsql default tablespace plsql;

CSS之box-sizing的用处简单介绍

前几天才发现有 box-sizing 这么个样式属性,研究了一番感觉很有意思, 通过指定容器的盒子模型类型,达到不同的展示效果 例如:当一个容器宽度定义为 width:100%;  之后,如果再增加 padding 或者 border 则会溢出父容器,是向外扩张的 如果使用该样式,指定为 box-sizing: border-box; 则 padding 和 border 就不会再溢出,而是向内收缩的,这个效果感觉非常实用, 特别是 input 和 textarea 等 现在设置 100% 再直

【玩转微信公众平台之七】 PHP语法简单介绍

经过多篇的努力,我们终于成为了微信公众平台的开发者.但是别高兴的太早,就跟修真小说一样:修炼多年武破虚空,飞升到仙界后本以为成为了天仙即可跳出三界外,不在五行中.可实际到了仙界才发现,成仙只是修行的第一步......没错,成为开发者也才只是第一步,因为现在你的微信公众平台还没有任何功能,说难听点就是小白,说好听点就是白马王子,说可爱点就是小白白,说黄色点就是洗白白,说...----------------要想在微信公众平台添加功能,那就需要写代码:既然说到写代码,那么肯定是要用php(如果用AS

Zookeeper简单介绍

转自:ZooKeeper学习第一期---Zookeeper简单介绍 一.分布式协调技术 在给大家介绍ZooKeeper之前先来给大家介绍一种技术--分布式协调技术.那么什么是分布式协调技术?那么我来告诉大家,其实分布式协调技术 主要用来解决分布式环境当中多个进程之间的同步控制,让他们有序的去访问某种临界资源,防止造成"脏数据"的后果.这时,有人可能会说这个简单,写一个调 度算法就轻松解决了.说这句话的人,可能对分布式系统不是很了解,所以才会出现这种误解.如果这些进程全部是跑在一台机上的

七、变量与常量的简单介绍

七.变量与常量的简单介绍 本文将介绍VB语言中的变量与常量. 基本概念 首先大家要明白变量和常量是很重要的东西,因为他们储存着程序运行中的各种数据.顾名思义,变量就是可以变的量,而常量就是不变的,这个概念和数学上的有点接近. 接下来我简单讲讲这两个重要的东西:计算机程序在不运行的时候,程序文件保存在硬盘上,当用户运行程序之后,系统就会把程序文件装进计算机的内存里面,无论在硬盘中还是内存中,程序数据都是以二进制的形式保存着的.当程序在运行的时候,可以把计算机的内存理解为一个超级大的棋盘,每个格子都

TensorFlow简单介绍和在centos上的安装

##tensorflow简单介绍: TensorFlow? is an open source software library for numerical computation using data flow graphs.https://www.tensorflow.org/TensorFlow是谷歌基于DistBelief进行研发的第二代人工智能学习系统,其命名来源于本身的运行原理.Tensor(张量)意味着N维数组,Flow(流)意味着基于数据流图的计算,TensorFlow为张量从图