Python Paste.deploy 笔记

转自:http://blog.csdn.net/sonicatnoc/article/details/6539716

首先python paste是一个WSGI工具包,在WSGI的基础上包装了几层,让应用管理和实现变得方便。说实话,Python Paste的文档做的真差劲!加之python代码可读性本来就不怎么滴,真费劲。

 

paste.deploy关键部分留个抓印:

1)python paste.deploy不能只装个paste.deploy包就可以工作了,还需要paste.script包

2)python paste.deploy中loadapp给的路径可用os.path.abspath(配置文件相对路径)得到配置文件的绝对路径,否则报找不到relative_to path...没搞明白怎么回事,目前不重要,放过。

3)python paste.deploy中filter,filter_factory,app,app_factory的规范在文档中都没怎么写清楚,我来给你补上吧:

- app是一个callable object,接受的参数(environ,start_response),这是paste系统交给application的,符合

WSGI规范的参数. app需要完成的任务是响应envrion中的请求,准备好响应头和消息体,然后交给start_response处理,并返回响应消息体。

- filter是一个callable object,其唯一参数是(app),这是WSGI的application对象,见(1),filter需要完成的工作是将application包装成另一个application(“过滤”),并返回这个包装后的application。

- app_factory是一个callable object,其接受的参数是一些关于application的配置信息:(global_conf,**kwargs),global_conf是在ini文件中default section中定义的一系列key-value对,而**kwargs,即一些本地配置,是在ini文件中,app:xxx section中定义的一系列key-value对。app_factory返回值是一个application对象

- filter_factory是一个callable object,其接受的参数是一系列关于filter的配置信息:(global_conf,**kwargs),global_conf是在ini文件中default section中定义的一系列key-value对,而**kwargs,即一些本地配置,是在ini文件中,filter:xxx section中定义的一系列key-value对。filter_factory返回一个filter对象

 

给个例子:

pastedeploylab.ini:

[python]  view plain copy
  1. [DEFAULT]  
  2. key1=value1  
  3. key2=value2  
  4. key3=values  
  5. [composite:pdl]  
  6. use=egg:Paste#urlmap  
  7. /:root  
  8. /calc:calc  
  9. [pipeline:root]  
  10. pipeline = logrequest showversion  
  11. [pipeline:calc]  
  12. pipeline = logrequest calculator  
  13. [filter:logrequest]  
  14. username = root  
  15. password = root123  
  16. paste.filter_factory = pastedeploylab:LogFilter.factory  
  17. [app:showversion]  
  18. version = 1.0.0  
  19. paste.app_factory = pastedeploylab:ShowVersion.factory  
  20. [app:calculator]  
  21. description = This is an "+-*/" Calculator   
  22. paste.app_factory = pastedeploylab:Calculator.factory  

 

pastedeploylab.py

[python]  view plain copy
  1. ''''' 
  2. Created on 2011-6-12 
  3. @author: Sonic 
  4. '''  
  5. import os  
  6. import webob  
  7. from webob import Request  
  8. from webob import Response  
  9. from paste.deploy import loadapp  
  10. from wsgiref.simple_server import make_server  
  11. #Filter  
  12. class LogFilter():  
  13.     def __init__(self,app):  
  14.         self.app = app  
  15.         pass  
  16.     def __call__(self,environ,start_response):  
  17.         print "filter:LogFilter is called."  
  18.         return self.app(environ,start_response)  
  19.     @classmethod  
  20.     def factory(cls, global_conf, **kwargs):  
  21.         print "in LogFilter.factory", global_conf, kwargs  
  22.         return LogFilter  
  23. class ShowVersion():  
  24.     def __init__(self):  
  25.         pass  
  26.     def __call__(self,environ,start_response):  
  27.         start_response("200 OK",[("Content-type""text/plain")])  
  28.         return ["Paste Deploy LAB: Version = 1.0.0",]  
  29.     @classmethod  
  30.     def factory(cls,global_conf,**kwargs):  
  31.         print "in ShowVersion.factory", global_conf, kwargs  
  32.         return ShowVersion()  
  33. class Calculator():  
  34.     def __init__(self):  
  35.         pass  
  36.       
  37.     def __call__(self,environ,start_response):  
  38.         req = Request(environ)  
  39.         res = Response()  
  40.         res.status = "200 OK"  
  41.         res.content_type = "text/plain"  
  42.         # get operands  
  43.         operator = req.GET.get("operator"None)  
  44.         operand1 = req.GET.get("operand1"None)  
  45.         operand2 = req.GET.get("operand2"None)  
  46.         print req.GET  
  47.         opnd1 = int(operand1)  
  48.         opnd2 = int(operand2)  
  49.         if operator == u'plus':  
  50.             opnd1 = opnd1 + opnd2  
  51.         elif operator == u'minus':  
  52.             opnd1 = opnd1 - opnd2  
  53.         elif operator == u'star':  
  54.             opnd1 = opnd1 * opnd2  
  55.         elif operator == u'slash':  
  56.             opnd1 = opnd1 / opnd2  
  57.         res.body = "%s /nRESULT= %d" % (str(req.GET) , opnd1)  
  58.         return res(environ,start_response)  
  59.     @classmethod  
  60.     def factory(cls,global_conf,**kwargs):  
  61.         print "in Calculator.factory", global_conf, kwargs  
  62.         return Calculator()  
  63. if __name__ == '__main__':  
  64.     configfile="pastedeploylab.ini"  
  65.     appname="pdl"  
  66.     wsgi_app = loadapp("config:%s" % os.path.abspath(configfile), appname)  
  67.     server = make_server('localhost',8080,wsgi_app)  
  68.     server.serve_forever()  
  69.     pass  

 

 

 

使用:

http://127.0.0.1:8080/

输出:

Paste Deploy LAB: Version = 1.0.0

http://127.0.0.1:8080/calc?operator=plus&operand1=12&operand2=23

输出:

UnicodeMultiDict([('operator', u'plus'), ('operand1', u'12'), ('operand2', u'23')])

RESULT= 35

====================================================

进一步猜测filter的使用过程:在paste deploy库中应该有类似这样的一段代码对application进行重组包装:

#

# 假设在ini文件中, 某条pipeline的顺序是filter1, filter2, filter3

# app, 那么,最终运行的app_real是这样组织的:

#



app_real = filter1(filter2(filter3(app)))



# 在app真正被调用的过程中,filter1.__call__(environ,start_response)被首先调用,若某种检查未通过,filter1做出反应;否则交给filter2__call__(environ,start_response)进一步处理,若某种检查未通过,filter2做出反应,中断链条,否则交给filter3.__call__(environ,start_response)处理,若filter3的某种检查都通过了,最后交给app.__call__(environ,start_response)进行处理。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值