zoukankan      html  css  js  c++  java
  • Python Paste.deploy 笔记

    首先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:

     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

     1 Created on 2011-6-12 
     2 @author: Sonic 
     3 '''  
     4 import os  
     5 import webob  
     6 from webob import Request  
     7 from webob import Response  
     8 from paste.deploy import loadapp  
     9 from wsgiref.simple_server import make_server  
    10 #Filter  
    11 class LogFilter():  
    12     def __init__(self,app):  
    13         self.app = app  
    14         pass  
    15     def __call__(self,environ,start_response):  
    16         print "filter:LogFilter is called."  
    17         return self.app(environ,start_response)  
    18     @classmethod  
    19     def factory(cls, global_conf, **kwargs):  
    20         print "in LogFilter.factory", global_conf, kwargs  
    21         return LogFilter  
    22 class ShowVersion():  
    23     def __init__(self):  
    24         pass  
    25     def __call__(self,environ,start_response):  
    26         start_response("200 OK",[("Content-type", "text/plain")])  
    27         return ["Paste Deploy LAB: Version = 1.0.0",]  
    28     @classmethod  
    29     def factory(cls,global_conf,**kwargs):  
    30         print "in ShowVersion.factory", global_conf, kwargs  
    31         return ShowVersion()  
    32 class Calculator():  
    33     def __init__(self):  
    34         pass  
    35       
    36     def __call__(self,environ,start_response):  
    37         req = Request(environ)  
    38         res = Response()  
    39         res.status = "200 OK"  
    40         res.content_type = "text/plain"  
    41         # get operands  
    42         operator = req.GET.get("operator", None)  
    43         operand1 = req.GET.get("operand1", None)  
    44         operand2 = req.GET.get("operand2", None)  
    45         print req.GET  
    46         opnd1 = int(operand1)  
    47         opnd2 = int(operand2)  
    48         if operator == u'plus':  
    49             opnd1 = opnd1 + opnd2  
    50         elif operator == u'minus':  
    51             opnd1 = opnd1 - opnd2  
    52         elif operator == u'star':  
    53             opnd1 = opnd1 * opnd2  
    54         elif operator == u'slash':  
    55             opnd1 = opnd1 / opnd2  
    56         res.body = "%s /nRESULT= %d" % (str(req.GET) , opnd1)  
    57         return res(environ,start_response)  
    58     @classmethod  
    59     def factory(cls,global_conf,**kwargs):  
    60         print "in Calculator.factory", global_conf, kwargs  
    61         return Calculator()  
    62 if __name__ == '__main__':  
    63     configfile="pastedeploylab.ini"  
    64     appname="pdl"  
    65     wsgi_app = loadapp("config:%s" % os.path.abspath(configfile), appname)  
    66     server = make_server('localhost',8080,wsgi_app)  
    67     server.serve_forever()  
    68     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)进行处理。
  • 相关阅读:
    Redis面试题(46题)
    公共组件及脚手架webpack模板
    css3中@font-face模块自定义字体
    字段加密实践(django-fernet-fields)
    django导入导出excel实践
    vue-loader和单页组件介绍
    Axios介绍和使用
    微服务架构理解及微服务架构局限性
    v-model的双向数据绑定(表单)
    eureka集群
  • 原文地址:https://www.cnblogs.com/zmlctt/p/4207139.html
Copyright © 2011-2022 走看看