Pasted Deployment是一套查找和配置WSGI应用和服务的系统。向WSGI application(WSGI应用,可调用对象)的用户提
供了一个简单的函数(loadapp)来从配置文件或是python的egg包中加载WSGI application。调用WSGI
application的程序只要求你的程序提供一个简单的单独的访问入口,所以application发布者并不需要暴露application的内部
的实现细节。
这样的好处是系统管理员可以很容易的安装和管理,并不需要掌握python,或是WSGI
Application的细节和它的container。 目前Paste
Deployment不需要依赖Paste项目中的其他部分,可以单独做为一个安装包。 Paste Deploy使用MIT协议发布。
Paste Deploy已经发布了1.0版本,是个活跃的开发项目。在1.0版本中,做了很多工作使它向后兼容,会在必要时包含对一些不再推荐使用的功能的警告。
名词解释
- application:应用,符合WSGI规范的可调用对象,接受参数(environ, start_response),调用start_response返回状态和HTTP消息头,返回结果作为消息体。
- filter:过滤器,可调用对象,类似python中的装饰器(decorator),接受一个application对象作为参数,返回一个封装后的application。
- app_factory:可调用对象,接受参数(global_config, **local_conf),返回application对象。
- composite_factory:可调用对象,接受参数(loader, global_config, **local_conf),loader有几个方法, get_app用于获取wsgi_app, get_filter用于加载filter, 返回application对象。
- filter_factory:可调用对象,接受参数(global_config, **local_conf),返回filter对象
Paste Deploy最主要的一方面是它定义的entry points(像paste.app_factory)
paste.deploy用的最多的是通过它的配置文件。
配置文件分为不同的段(section),Paste Deply关心的几个段(section)都有前缀,像 app:main 还有 filter:errors ————冒号后面的部分是段的名字(name of section),冒号前的部分给出段的类型(type of section)。其他的段(section)会被忽略。
paste配置文件就是普通的INI文件格式,可以使用缩进的多行来作为一行的延续。开头的”#”井号或是”;”分号后面是注释。 格式像下面这样定义
所有的值都是字符串(不需要用引号括起来),每个段的名字和段中值的名字都是大小写敏感的,可以包含标点符号和空白符,最后键和值两边的空白符都会被去掉。以空白符开始的行被认为是上一行的延续。
通常会添加两个段,一个叫做main的应用段([app:main])和一个服务段([server:main])。[composite:...]表示转发到多个应用的东西。
下面是一个典型的配置文件使用了paste.urlmap来组合多个应用。
下面解释详细解释每一段:
这是一个composite段,它会转发请求到其他的应用。
use = egg:Paste#urlmap 表示使用paste包中的叫做urlmap的
composite application。
urlmap 是一个通用的
composite application —— 它把请求转到其他的应用。这里有几个应用,像”home”, “blog”, “wiki”和”config:cms.ini”。最后一个只是指向同一个文件夹下的cms.ini配置文件。
接下来:
egg:Paste#static 是另一个简单的应用,处理非动态文件。需要参数 document_root, 指定静态文件根目录。还可以使用变量替换,变量是在[DEFAULT]段中定义的,定义替换变量作用标签
%(var_name)s。上面用到的特殊变量
%(here)s 指这个配置文件所在的文件夹。
接下来,看看
第二个段只是指向BlogApp应用,database会做为参数传递到应用中。
最后
这个段和前一个段很像,一个重要的不同点是它直接指向mysiki.main模块中的应用而不是egg包中的入口点(entry point)。指向哪个应用定义由冒号分隔的两部分组成:冒号左边的模块的名字,右边是从模块中引用的应用。
以上就是最常用的功能。
配置文件中的DEFAULT段的选项会被作为全局变量。在其他段中的选项做为局部变量传到相应的application中,如果局部选项中的键和
DEFAULT中的键一样,局部选项中键会被忽略(global_config和local_config中都没有),如果想覆盖全局变量中的键值,使用set字段,如
使用loadapp生成test应用时,会调用test.test,和调用app_factory一样,传入global_config和
local_config,global_config中name=test,被局部配置覆盖了,global_config中version还是
1.0,局部配置中没有version。
使用call时是会转成相应的factory(app转成app_factory,filter转成
filter_factory,composite转成composite_factory)但是调用的方法名,只能是函数,不能是类的方法,虽然在代码
注释中写可以导入如”obj.method”,但是其在引入可调用对象时是直接使用getattr会报错,还是不能有点”.”
示例代码如下:test_wsgi.ini
test_wsgi.py
- import os
-
- import eventlet
- from eventlet import wsgi, listen
- from paste import deploy
-
- _path = os.path.dirname(__file__)
-
- #application object
- class TestApp(object):
- @classmethod
- def factory(cls, global_conf, **local_conf):
- return cls()
-
- def __call__(self, env, start_response):
- #print env
- start_response("200 OK", ())
- return ["welcome"]
-
- def test_app(self, env, start_response):
- start_response("200 OK", ())
- return ["welcome"]
-
- test2_factory = TestApp.factory
-
- def composite_factory(loader, global_config, **local_config):
- #print env, start_response, args, kwargs
- return TestApp()
-
- def filter_factory(global_config, **local_config):
- import time
- def fiter(app):
- print "now is %f" % time.time()
- return app
- return filter
-
- def main():
- f = "config:%s" % os.path.join(_path, "test_paste.ini")
- host = "0.0.0.0"
- server_list = [("test1", 8001),
- ("test2", 8002),
- ("test3", 8003),]
-
- servers = []
- for app_name, port in server_list:
- _socket = listen((host, port))
- app = deploy.loadapp(f, app_name)
-
- print "%s is starting" % app_name
- servers.append(eventlet.spawn(wsgi.server, _socket, app))
-
- for server in servers:
- server.wait()
-
- if __name__ == '__main__':
- main()
参考: