1. 缘起

当看到OpenStack的api-paste.ini中大量出现的composite,pipline,filter,app之后顿时觉得不淡定了,这些都是啥,是啥!在详细研究一番之后,却发现了意外的惊喜,好似发现了另一个世界,也明白了OpenStack使用这套东西却有他的高明之处。

本文不会阐述任何与OpenStack相关的paste内容,就是很纯粹地来讲paste,讲paste这个美妙的世界。所以本篇被归类为python分类。

2. paste的世界观

paste单词本意为:糊料,糨糊,是不是想到这是一种粘合剂。你猜对了,就是粘合剂。

继续,那么我们在看看下面这些关键词:

filter:过滤器,滤网。

pipline:管道

app:application 应用,在这个语境下我举个例子吧,lavabo(洗手盆),fish tank(鱼缸)...... 这些都是应用

composite:意为合成,或合成结构。

那么这些到底都是什么,有没有想到管道工程,估计你也猜到了,估计paste作者的灵感就是从这地方来的吧。

为了搞明白这个,好不容易找了一张图来说明这个。

我也不是专业管道工程的,所以按我的理解给关键字归归类吧。

paste是粘合剂,这里暂且看做是结合处的钉子吧。

filter:过滤器,这里可以就以图中的7(假设里面有过滤网),8 (假设里面有过滤网),12(压力表),17(流量表)指代吧。

app:这里就用13来指代吧,就是水龙头了吧。

pipeline:管线,1, 2, 3,5,15都算吧。

composite:这个用6来指代就很贴切了。

再回过头来看看,paste的整个体系就浮现在眼前了吧。

3. paste的目的与用心

有了上面一整套的东西(积木),或者说管道工程的世界观,paste的目的是什么,它要做什么?用过django,flask或者tornado的人一定知道,一个url一般与一个类或方法对应,以典型的flask为例:

@app.route('/')
def index():return 'Index Page'
@app.route('/hello')
def hello():return 'Hello World'

这里可以看到“/”对应了index() ,“/hello”对应了hello()。这里的装饰器被称为route。

其实单从URL上来说,是存在某种逻辑关系的,这种逻辑关系就像管道工程!

这种URL有可能必须经过某个分发(多通管道),又经过某个验证过程(过滤)之后再最终执行某个过程(应用)。

估计发明paste的作者在思考怎么把这种虚拟的逻辑关系用现实中的物体表示的时候,看到身边的管道之后就开始浮现连篇了吧。取名也被叫做了paste,确实是煞费苦心。

4. 实例

管道中的液体,暂且假设为水,那么我们假设有如下URL,假设这是一家酒店:

/master_valve/hydrant                                 #/总阀/消防栓

/master_valve/tap                                        #/总阀/水龙头

/master_valve/boiler/shower                       #/总阀/锅炉/花洒(淋浴房)

/master_valve/purifier/drinking_fountain    #/总阀/净化器/直饮水机

根据上面的URL我们用paste来描述出它们的逻辑关系

首先应该确定关键词:

composite:master_valve

filter:purifier,boiler

app:hydrant,tap,shower,drinking_fountain

按照这一逻辑,水从总阀中引出后经过管线进入一个多通管道,被分别引入消防栓,水龙头,净水器和锅炉。从净水器引出后进入直饮水机,而从锅炉引出后进入淋浴房的花洒。

5. 动手描述逻辑关系

根据上面的假设,我们开始编写一个ini用来描述这种逻辑关系

下面我们来写配置文件configured.ini,逻辑关系是很清晰的,一目了然。

[app:hydrant]
paste.app_factory = hydrant:app_factory
in_arg = water[app:tap]
paste.app_factory = tap:app_factory
in_arg = water[app:shower]
paste.app_factory = shower:app_factory
in_arg = hot_water[app:drinking_fountain]
paste.app_factory = drinking_fountain:app_factory
in_arg = pure_water[filter:purifier]
paste.filter_app_factory = purifier:filter_app_factory
in_arg = water[filter:boiler]
paste.filter_app_factory = boiler:filter_app_factory
in_arg = water[pipeline:pip_to_shower]
pipeline = boiler shower[pipeline:pip_to_drinking_fountain]
pipeline = purifier drinking_fountain[composite:valve]
use = egg:Paste#urlmap
/hydrant = hydrant
/tap = tap
/boiler/shower = pip_to_shower
/purifier/drinking_fountain = pip_to_drinking_fountain[composite:main]
use = egg:Paste#urlmap
/master_valve: valve

这里需要注意的是里面的命名规则,还是来解释一下这个配置文件吧。

里面有app,filter,pipeline,composite,与之对应的是里面要确定对应的factory,以

[app:tap]
paste.app_factory = tap:app_factory
in_arg = water

为例,表示tap的paste.app_factory存在于tap(tap.py)的app_factory中,这是一个方法,在后面我们会提到。

同样的,对于filter也是类似的,只不过换成了paste.filter_app_factory,在真正实现的时候,要注意与app的factory的区别。

接下来就是pipeline,它主要起到组合的作用,将filter(过滤器)和app(应用)组合起来,形成一条管线。

注意:本来,按逻辑上来讲,水从master_valve(总阀)出来也应该经过pipeline(管线)再到tap(水龙头)或hydrant(消防栓),这里只是形式上省略了。

[composite:valve]
use = egg:Paste#urlmap
/hydrant = hydrant
/tap = tap
/boiler/shower = pip_to_shower
/purifier/drinking_fountain = pip_to_drinking_fountain

这一部分,Paste#urlmap表示默认使用了Paste.urlmap

在http://pythonpaste.org/deploy/ 上有一段关于urlmap的解释:

use = egg:Paste#urlmap means to use the composite application named urlmap from the Paste package. urlmap is a particularly common composite application – it uses a path prefix to map your request to another application.

翻译过来大意为:

use = egg:Paste#urlmap意味着直接使用来自于Paste包的urlmap的composite应用。 urlmap是特别常见的composite应用——它使用路径前缀来映射将你的请求与其他应用对应起来。

基本含义就是说,这是Paste已经提供好的一个composite,如果你想自定义就需要另外写一个composite_factory了。

paste其实还提供很多已经写好的factory,可以分别用于app,filter,composite,pipeline,例如:egg:Paste#static。

/hydrant = hydrant

这些就是路径对应,不做过多解释。

6. 实现里面的类

建立一个工程,里面文件结构如下:

配置文件configured.ini在第5节中已经展示过,这里就不再提及了。

从总阀开始说起,

#master_valve.py
#pip install paste
#pip install PasteDeploy
#import os
#os.chdir('D:/py_test/paste/hotel')
if __name__ == '__main__':from paste import httpserverfrom paste.deploy import loadapphttpserver.serve(loadapp('config:configured.ini', relative_to='.'),host='0.0.0.0', port='8080')

这里使用了httpserver,在loadapp中将配置文件载入,并绑定在8080端口。

这里要注意的是路径问题,如果你是在windows下运行,可能需要os.chdir('/xxx')定位到你所在的目录中去。

还有就是需要安装paste和PasteDeploy,使用pip安装即可。

下面介绍的是四个应用(app)

水龙头

#tap.py
class Tap(object):def __init__(self, in_arg):self.in_arg = in_argdef __call__(self, environ, start_response):print 'Tap'status = '200 OK'response_headers = [('Content-Type', 'text/plain')]start_response(status, response_headers)return ['%s, %s!\n' % (self.in_arg, 'Tap')]
def app_factory(global_config, in_arg):return Tap(in_arg)

花洒(淋浴房)

#shower.py
class Shower(object):def __init__(self, in_arg):self.in_arg = in_argdef __call__(self, environ, start_response):print 'Shower'status = '200 OK'response_headers = [('Content-Type', 'text/plain')]start_response(status, response_headers)return ['%s, %s!\n' % (self.in_arg, 'Shower')]
def app_factory(global_config, in_arg):return Shower(in_arg)

消防栓

#hydrant.py
class Hydrant(object):def __init__(self, in_arg):self.in_arg = in_argdef __call__(self, environ, start_response):print 'Hydrant'status = '200 OK'response_headers = [('Content-Type', 'text/plain')]start_response(status, response_headers)return ['%s, %s!\n' % (self.in_arg, 'Hydrant')]
def app_factory(global_config, in_arg):return Hydrant(in_arg)

直饮水机

#drinking_fountain.py
class DrinkingFountain(object):def __init__(self, in_arg):self.in_arg = in_argdef __call__(self, environ, start_response):print 'DrinkingFountain'status = '200 OK'response_headers = [('Content-Type', 'text/plain')]start_response(status, response_headers)return ['%s, %s!\n' % (self.in_arg, 'DrinkingFountain')]
def app_factory(global_config, in_arg):return DrinkingFountain(in_arg)

这四个应用的结构基本是类似的,需要注意的是factory方法的参数,这会与后面介绍的filter的factory有所不同。

每一个应用类内部的__init__和__call__方法是需要自己实现的,__call__方法返回的字符串将会在web页面上显示,start_response(status, response_headers)语句及相关参数涉及到wsgi,因为涉及的知识更多,这里就不再展开了。

本博可能会另外写一篇文章专门阐述wsgi,敬请关注......

应用部分介绍结束。

下面就是过滤器了,这里一共有两个过滤器,分别是锅炉和净水器。

锅炉

#boiler.py
class Boiler(object):def __init__(self, app, in_arg):self.app = appself.in_arg = in_argdef __call__(self, environ, start_response):print 'Boiler'return self.app(environ, start_response)
def filter_app_factory(app, global_config, in_arg):return Boiler(app, in_arg)

净水器

#purifier.py
class purifier(object):def __init__(self, app, in_arg):self.app = appself.in_arg = in_argdef __call__(self, environ, start_response):print 'purifier'return self.app(environ, start_response)
def filter_app_factory(app, global_config, in_arg):return purifier(app, in_arg)

注意到过滤器和应用的不同了吧,在实现过滤器factory的时候,必须要将app参数带入,且必须是第一个位置

这里过滤器中并没有真正过滤什么,实际上应该在__call__中进行一定的处理,设定一定的条件,将一定的条件拦截。

由于这里只是粗略的实现,只做逻辑上的说明。

7. 执行

python master_valve.py

在浏览器中输入

http://127.0.0.1:8080/master_valve/tap

此时,程序只是运行了tap这个app。

再次在浏览器中输入

http://127.0.0.1:8080/master_valve/boiler/shower

此时,水经过锅炉,再进入花洒,执行了两个app。

Paste模块的世界相关推荐

  1. html5魔塔存档模块,魔塔世界完整版源码

    Delay 23 ElseIf hong=4 inx=462 iny=573 inz="383C3D" Delay 23 EndIf Delay 23 Return 红的百分比 / ...

  2. Meta祭出元宇宙「阿拉丁神灯」!LeCun称世界模型将带来像人一样的AI

      视学算法报道   编辑:桃子 好困 袁榭 拉燕 [新智元导读]2022年2月24日凌晨,在Meta AI实验室讨论会上,小扎亲自带队公布了多项技术内容:语音生成元宇宙场景的Builder Bot. ...

  3. Yann LeCun:未来几十年AI研究的最大挑战是「预测世界模型」

    来源:机器之心 本文约4000字,建议阅读8分钟 本文为你介绍一种叫做分层 JEPA(联合嵌入预测架构)的架构. LeCun 认为,构造自主 AI 需要预测世界模型,而世界模型必须能够执行多模态预测, ...

  4. Yann LeCun 最新发声:自监督+世界模型,让 AI 像人类与一样学习与推理

    来源:AI科技评论 本文约6100字,建议阅读10+分钟 Yann LeCun提倡下一代AI系统将不再依赖于精心标注的数据集. 如何突破当代人工智能(AI)的瓶颈?不同学者存在不同观点. 总体来看可以 ...

  5. 图灵奖获得者Yann LeCun:未来几十年AI研究的最大挑战是「预测世界模型」

    来源:机器之心 LeCun 认为,构造自主 AI 需要预测世界模型,而世界模型必须能够执行多模态预测,对应的解决方案是一种叫做分层 JEPA(联合嵌入预测架构)的架构.该架构可以通过堆叠的方式进行更抽 ...

  6. cesium 知乎_Cesium 源码笔记[2] CesiumWidget模块的实例化过程 ver1.67

    四叶小天使! 上承 CesiumWidget实际上和Viewer差不多.以下两句代码用于初始化,效果是差不多的. const widget = new Cesium.CesiumWidget('id选 ...

  7. Python-Django毕业设计“小世界”私人空间(程序+Lw)

    该项目含有源码.文档.程序.数据库.配套开发软件.软件安装教程 项目运行 环境配置: Pychram社区版+ python3.7.7 + Mysql5.7 + HBuilderX+list pip+N ...

  8. 《像计算机科学家一样思考Python》——第4章 案例研究:接口设计 4.1 乌龟世界...

    本节书摘来自异步社区<像计算机科学家一样思考Python>一书中的第4章,第4.1节,作者[美]Allen B. Downey,赵普明 译,更多章节内容可以访问云栖社区"异步社区 ...

  9. angular react_Angular 2 vs React:将会有鲜血

    angular react Angular 2 has reached Beta and appears poised to become the hot new framework of 2016. ...

最新文章

  1. linux oracle 配置监听器
  2. 通过crontab调度java -jar任务提示nohup: failed to run command `java': No such file or directory...
  3. JSP页面空指针异常调错办法之weblogic
  4. Leetcode - 144. Binary Tree Preorder Traversal (层次遍历)
  5. 使用ToughMySQL为ToughRADIUS系统提供数据存储
  6. javaweb如何定位
  7. 【Unity3D基础】让物体动起来②--UGUI鼠标点击逐帧移动
  8. bootstrap媒体查询类型的值_Redis系列-数据类型sorted_set
  9. ubuntu 安装php redis,ubuntu上安装php redis
  10. pytorch Inception代码实现
  11. Eclipse插件系列:spring插件配置
  12. oracle sql 查询无数据_信运大讲堂丨ORACLE数据库SQL和索引
  13. mysql 分表例子_mysql分表查询的简单例子
  14. 计算机毕业设计ssm智能停车场管理系统
  15. C#发送邮件,包含发送附件
  16. VSCode中设置ArcGIS python工具箱.pyt文件代码高亮
  17. 2020/03/01 03-Django模板DTL使用
  18. Ubuntu 12.10 禁用来宾账户和远程登录
  19. office 2007 word空格消失的问题
  20. 穿越功耗墙,从哪些方面提升性能?

热门文章

  1. [编解码] 关于base64编码的原理及实现
  2. C++ 容器vector的范例学习
  3. Google 翻译的妙用
  4. 邮件服务器轻松组建 友旺MG1200功能介绍
  5. Servlet -- 重定向
  6. Case when then esle end
  7. 通过joystick遥感和按键控制机器人--11
  8. 一次bug死磕经历之Hbase堆内存小导致regionserver频繁挂掉
  9. hibernate ORM related
  10. Java对象的生命周期与作用域的讨论(转)