1. WSGI Server <-----> WSGI Middleware<-----> WSGI Application 

1.1 WSGI Server

  wsgi server可以理解为一个符合wsgi规范的web server,接收request请求,封装一系列环境变量,按照wsgi规范调用注册的wsgi app,最后将response返回给客户端。

1.2 WSGI Application

wsgi application就是一个普通的callable对象,当有请求到来时,wsgi server会调用这个wsgi application。

   这个对象接收两个参数,通常为environ,start_response。

   environ可以理解为环境变量,跟一次请求相关的所有信息都保存在了这个环境变量中,包括服务器信息,客户端信息,请求信息。

   start_response是一个callback函数,wsgi application通过调用start_response,将response headers/status 返回给wsgi server。

   此外这个wsgi application会return一个iterator对象 ,这个iterator就是response body。

1.3 WSGI Middleware

  中间件是为了使应用程序拥有额外的行为而存在的。如果你不能随意决定是否将它放到程序的前面,它就不再是中间件了。而是程序的一部分。

  比如:URL dispatch功能,权限判断。

1.4 WSGI模型示例
 
from wsgiref.simple_server import make_server

URL_PATTERNS= (
('hi/','say_hi'),
('hello/','say_hello'),
) class Dispatcher(object): def _match(self,path):
path = path.split('/')[1]
for url,app in URL_PATTERNS:
if path in url:
return app def __call__(self,environ, start_response):
path = environ.get('PATH_INFO','/')
app = self._match(path)
if app :
app = globals()[app]
return app(environ, start_response)
else:
start_response("404 NOT FOUND",[('Content-type', 'text/plain')])
return ["Page dose not exists!"] def say_hi(environ, start_response):
start_response("200 OK",[('Content-type', 'text/html')])
return ["kenshin say hi to you!"] def say_hello(environ, start_response):
start_response("200 OK",[('Content-type', 'text/html')])
return ["kenshin say hello to you!"] app = Dispatcher() httpd = make_server('', 8000, app)
print "Serving on port 8000..."
httpd.serve_forever()

2.WebOb

  WebOb是一个用于对WSGI Request环境进行包装,以及用于创建WSGI Response的一个包。

  WebOb把WSGI的几个参数、返回的方法都封装成了Reqeust、Response这两个对象,同时还提供了一个使用方便的Exception对象。

  Related API Link: http://docs.webob.org/en/latest/reference.html

2.1 Request

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)

2.2 Response

from webob import Response
from pprint import pprint
res = Response(content_type='text/plain', charset=None)
f = res.body_file
f.write('hey')
f.write('test') # pprint(res.status)
# pprint(res.headerlist)
# pprint(res.body)

2.3 Full Sample about Request and Response

from webob import Request
from webob import Response
from webob.dec import wsgify # @wsgify
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

2.4 Exception

  下述总结了WebOb对于HTTP返回码的类定义。

Exception
HTTPException
HTTPOk
* - :class:`HTTPOk`
* - :class:`HTTPCreated`
* - :class:`HTTPAccepted`
* - :class:`HTTPNonAuthoritativeInformation`
* - :class:`HTTPNoContent`
* - :class:`HTTPResetContent`
* - :class:`HTTPPartialContent`
HTTPRedirection
* - :class:`HTTPMultipleChoices`
* - :class:`HTTPMovedPermanently`
* - :class:`HTTPFound`
* - :class:`HTTPSeeOther`
* - :class:`HTTPNotModified`
* - :class:`HTTPUseProxy`
* - :class:`HTTPTemporaryRedirect`
HTTPError
HTTPClientError
* - :class:`HTTPBadRequest`
* - :class:`HTTPUnauthorized`
* - :class:`HTTPPaymentRequired`
* - :class:`HTTPForbidden`
* - :class:`HTTPNotFound`
* - :class:`HTTPMethodNotAllowed`
* - :class:`HTTPNotAcceptable`
* - :class:`HTTPProxyAuthenticationRequired`
* - :class:`HTTPRequestTimeout`
* - :class:`HTTPConflict`
* - :class:`HTTPGone`
* - :class:`HTTPLengthRequired`
* - :class:`HTTPPreconditionFailed`
* - :class:`HTTPRequestEntityTooLarge`
* - :class:`HTTPRequestURITooLong`
* - :class:`HTTPUnsupportedMediaType`
* - :class:`HTTPRequestRangeNotSatisfiable`
* - :class:`HTTPExpectationFailed`
* - :class:`HTTPUnprocessableEntity`
* - :class:`HTTPLocked`
* - :class:`HTTPFailedDependency`
* - :class:`HTTPPreconditionRequired`
* - :class:`HTTPTooManyRequests`
* - :class:`HTTPRequestHeaderFieldsTooLarge`
* - :class:`HTTPUnavailableForLegalReasons`
HTTPServerError
* - :class:`HTTPInternalServerError`
* - :class:`HTTPNotImplemented`
* - :class:`HTTPBadGateway`
* - :class:`HTTPServiceUnavailable`
* - :class:`HTTPGatewayTimeout`
* - :class:`HTTPVersionNotSupported`
* - :class:`HTTPNetworkAuthenticationRequired`

WSGI学习系列WebOb的更多相关文章

  1. WSGI学习系列Paste

    Paste has been under development for a while, and has lots of code in it. The code is largely decoup ...

  2. WSGI学习系列WSME

    Introduction Web Services Made Easy (WSME) simplifies the writing of REST web services by providing ...

  3. WSGI学习系列Pecan

    Pecan Introduce Pecan是一个轻量级的基于Python的Web框架, Pecan的目标并不是要成为一个“full stack”的框架, 因此Pecan本身不支持类似Session和D ...

  4. WSGI学习系列多种方式创建WebServer

    def application(environ, start_response): start_response('200 OK', [('Content-Type', 'text/html')]) ...

  5. WSGI学习系列eventlet.wsgi

    WSGI是Web Service Gateway Interface的缩写. WSGI标准在PEP(Python Enhancement Proposal)中定义并被许多框架实现,其中包括现广泛使用的 ...

  6. 分布式学习系列【dubbo入门实践】

    分布式学习系列[dubbo入门实践] dubbo架构 组成部分:provider,consumer,registry,monitor: provider,consumer注册,订阅类似于消息队列的注册 ...

  7. Entity Framework Code First学习系列目录

    Entity Framework Code First学习系列说明:开发环境为Visual Studio 2010 + Entity Framework 5.0+MS SQL Server 2012, ...

  8. WCF学习系列汇总

    最近在学习WCF,打算把一整个系列的文章都”写“出来,包括理论和实践,这里的“写”是翻译,是国外的大牛写好的,我只是搬运工外加翻译.翻译的不好,大家请指正,谢谢了.如果觉得不错的话,也可以给我点赞,这 ...

  9. EF(Entity Framework)系统学习系列

    好久没写博客了,继续开启霸屏模式,好了,废话不多说,这次准备重新系统学一下EF,一个偶然的机会找到了一个学习EF的网站(http://www.entityframeworktutorial.net/) ...

随机推荐

  1. java多线程同步(转)

    原文地址:http://developer.51cto.com/art/201509/490965.htm 一.场景 因为当我们有多个线程要同时访问一个变量或对象时,如果这些线程中既有读又有写操作时, ...

  2. 一)如何开始 ehcache ?

    官网地址 http://www.ehcache.org/ 从哪开始 第一步优先下载 http://www.ehcache.org/downloads/ 下载 Ehcache 2.10.0 .tar.g ...

  3. PrefixHeader.pch 在工程中的使用

    1)  新建一个pch文件 2) 在 工程 Build Settings 中搜索 header  将Precompile Prefix Header 置为YES 2) 选中pch文件, 将右侧相对路径 ...

  4. 20155323 2016-2017-2 《Java程序设计》第6周学习总结

    20155323 2016-2017-2 <Java程序设计>第6周学习总结 教材学习内容总结 串流:衔接数据的来源和目的地就是串流对象. I/O操作主要是指使用Java进行输入,输出操作 ...

  5. COM是如何实现STA的

    Rather than using thread synchronization objects (mutexes, semaphores, and so forth) to control acce ...

  6. 洛谷P3066 [USACO12DEC]逃跑的Barn (线段树合并)

    题目描述It's milking time at Farmer John's farm, but the cows have all run away! Farmer John needs to ro ...

  7. [php] try - catch exceptiong handler

    //http://stackoverflow.com/questions/1241728/can-i-try-catch-a-warningOne possibility is to set your ...

  8. FP-Growth in Spark MLLib

    并行FP-Growth算法思路 上图的单线程形成的FP-Tree. 分布式算法事实上是对FP-Tree进行分割,分而治之 首先,假设我们只关心...|c这个conditional transactio ...

  9. signalR常见问题

    一.安装signalR会对应安装自己的NewJson包,如果引用了含有不同NewJson包的dll组件,会造成版本不一致.必须在运行环境中指出使用目标版本. 问题截图: 解决方式: <runti ...

  10. wpf控件拖动

    Thumb 拖动 上代码! <Window x:Class="Thumb控件移动.MainWindow" xmlns="http://schemas.microso ...