WSGI学习系列WebOb
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功能,权限判断。
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的更多相关文章
- WSGI学习系列Paste
Paste has been under development for a while, and has lots of code in it. The code is largely decoup ...
- WSGI学习系列WSME
Introduction Web Services Made Easy (WSME) simplifies the writing of REST web services by providing ...
- WSGI学习系列Pecan
Pecan Introduce Pecan是一个轻量级的基于Python的Web框架, Pecan的目标并不是要成为一个“full stack”的框架, 因此Pecan本身不支持类似Session和D ...
- WSGI学习系列多种方式创建WebServer
def application(environ, start_response): start_response('200 OK', [('Content-Type', 'text/html')]) ...
- WSGI学习系列eventlet.wsgi
WSGI是Web Service Gateway Interface的缩写. WSGI标准在PEP(Python Enhancement Proposal)中定义并被许多框架实现,其中包括现广泛使用的 ...
- 分布式学习系列【dubbo入门实践】
分布式学习系列[dubbo入门实践] dubbo架构 组成部分:provider,consumer,registry,monitor: provider,consumer注册,订阅类似于消息队列的注册 ...
- Entity Framework Code First学习系列目录
Entity Framework Code First学习系列说明:开发环境为Visual Studio 2010 + Entity Framework 5.0+MS SQL Server 2012, ...
- WCF学习系列汇总
最近在学习WCF,打算把一整个系列的文章都”写“出来,包括理论和实践,这里的“写”是翻译,是国外的大牛写好的,我只是搬运工外加翻译.翻译的不好,大家请指正,谢谢了.如果觉得不错的话,也可以给我点赞,这 ...
- EF(Entity Framework)系统学习系列
好久没写博客了,继续开启霸屏模式,好了,废话不多说,这次准备重新系统学一下EF,一个偶然的机会找到了一个学习EF的网站(http://www.entityframeworktutorial.net/) ...
随机推荐
- 2018.07.26NOIP模拟 魔法数字(数位dp)
魔法数字 题目背景 ASDFZ-NOIP2016模拟 题目描述 在数论领域中,人们研究的基础莫过于数字的整除关系.一般情况下,我们说整除总在两个数字间进行,例如 a | b(a能整除b)表示 b 除以 ...
- [转载][翻译]Go的50坑:新Golang开发者要注意的陷阱、技巧和常见错误[2]
Golang作为一个略古怪而新的语言,有自己一套特色和哲学.从其他语言转来的开发者在刚接触到的时候往往大吃苦头,我也不例外.这篇文章很细致地介绍了Golang的一些常见坑点,读完全篇中枪好多次.故将其 ...
- Java中BufferedReader和scanner
Scanner 和BufferedReader同样能实现将键盘输入的数据送入程序, import java.io.*;import java.util.Scanner;public class C { ...
- button设置边宽和圆角
UIButton *meifuButton = [UIButton buttonWithType:UIButtonTypeSystem]; [meifuButton setTit ...
- Delphi for iOS开发指南(8):在iOS应用程序中使用Tab组件来显示分页
Delphi for iOS开发指南(8):在iOS应用程序中使用Tab组件来显示分页 在FireMonkey iOS应用程序中的Tab Tab由FMX.TabControl.TTabControl定 ...
- Android-ByteUtil工具类
Byte处理转换相关的工具类: public class ByteUtil { private ByteUtil(){} /** * 把byte[] 转成 Stirng * @param bytes ...
- [Openwrt 项目开发笔记]:USB挂载& U盘启动(三)
[Openwrt项目开发笔记]系列文章传送门:http://www.cnblogs.com/double-win/p/3888399.html 正文: 在上一篇中,我结合Netgear Wndr370 ...
- SQL反模式-1
SQL反模式讲了很多数据库设计中遇到的难题.跟我最近的工作很相关.因此特意拜读了下.本文主要讲解"多值列"和"幼稚的树" 多值列要分成映射表,比如(A,B),其 ...
- log4j学习(二)不同类的日志输出到不同的文件
目的:一个应用中有两个不同作用的后台服务,我们需要把他们的日志分开,存放到2个不同的日志文件中. 办法:需要在log4j.properties文件中配置两个不同的logger和对应的appender ...
- elk部署心得
一.ElasticSearch 部署 1.配置文件里node.name 要不一致. vim /etc/elasticsearch cluster.name: aubin-cluster # 集群名称 ...