首先说明一下,从1.1开始,Pyramid的项目模板开始改叫scaffold(脚手架)了,不过还是习惯叫它项目模板,跟web开发中使用的模板在中文里面还没有那么混淆吧。
一、目前Pyramid提供的项目模板
Pyramid项目模板之间主要靠持久化机制,URL映射机制来区分,目前主要提供以下几种:
* pyramid_starter: 使用traversal机制进行URL映射,无持久化支持
* pyramid_zodb: 使用traversal机制进行URL映射,使用ZODB提供持久化支持
* pyramid_routesalchemy: 使用分发机制(即Route机制)进行URL映射,使用SQLAlchemy提供持久化支持
* pyramid_alchemy: 使用traversal机制进行URL映射,使用SQLAlchemy提供持久化支持
二、创建一个项目
这个跟原来的pylons一模一样,直接运行
paster create -t pyramid_starter
然后在接下来的提示中输入项目名就可以创建一个项目。
这里要注意一下的是,Pyramid(Pylons也一样)项目的名字推荐采用类似MyProject(单词首字母大写,单词间无间隔符)这样的命名方式,Pyramid会建立一个叫MyProject的目录。在该目录下,Pyramid会再建一个叫myproject(单词全小写,无间隔符,符合PEP8规范)的目录,这个目录就是该项目所有代码、开发模板的推荐存放处。
三、建立开发环境
运行python setup.py develop即可完成这个步骤。
这一步是以前pylons项目所没有的。主要工作就是刷新一下PKG-INFO,在Pyramid环境的site-packages中加入一个MyProject.egg-link文件,指向当前项目所在的目录,并在easy-install.pth 中加入该项目所在的目录。这样就可以在整个Pyramid环境中引用这个项目了。最后就是查找新建项目的依赖包,如果本地环境没有,则从网上下载安装。
个人感觉这个步骤不如pylons清晰,特别是如果本机开发的项目比较多,就会造成很多link,而这些项目之间并不一定都需要相互依赖。还不如直接在IDE中设置项目依赖关系更清楚、方便,可以单独设置每个项目的依赖关系。
四、单元测试
Pyramid貌似对单元测试相当重视,不再需要单独装nosetests貌似也可以直接跑整个项目的单元测试。
直接运行命令
python setup.py test -q
即可执行整个项目的单元测试。
不过目前还不知道特定指定某个包的单元测试如何做,也还不清楚怎么使用这个命令计算覆盖率,需要空了再来研究一下。
五、运行
很简单,跟pylons一样,直接运行
paster serve development.ini
即可启动服务。当然也可以加--reload参数以便检测到文件变更自动重启服务。
这里development.ini就是这个项目的配置文件。
六、项目结构
打开我们创建的这个新项目,我们可以看到以下目录结构:
MyProject/
|-- CHANGES.txt
|-- development.ini
|-- MANIFEST.in
|-- myproject
| |-- __init__.py
| |-- resources.py
| |-- static
| | |-- favicon.ico
| | |-- logo.png
| | ‘-- pylons.css
| |-- templates
| | ‘-- mytemplate.pt
| |-- tests.py
| ‘-- views.py
|--production.ini
|--README.txt
|--setup.cfg
‘--setup.py
这里我们首先看一下Myroject这个项目根目录下的几个文件:
1. CHANGES.txt
本项目的变更文件,推荐采用ReST格式编写
2. RADME.txt
项目描述文件,推荐采用ReST格式编写
3. development.ini
开发时参数配置文件
4. production.ini
运行时参数配置文件
5. setup.cfg
这是setup.py使用的配置文件
6. MANIFEST.in
打包清单,列出了打包时需要一起打到python程序包中的文件
7. setup.py
标准的setuptools的setup.py文件,用于测试、分发该项目
七、包结构
在MyProject项目目录中,还有一个叫myproject的包目录,这个目录下包含了如下内容
1. __init__.py
初始化文件。包含了一些启动本项目的指令。
2. resources.py
资源定义文件,提供URL映射所需的站点结构
3. templates
存放开发模板文件的目录
4. tests.py
存放单元测试
5. views.py
存放可调用视图
本文提到的示例材料均源于Pyramid官方网站
Saturday, July 30, 2011
Friday, July 29, 2011
Pyramid 学习笔记:简单的Hello world
使用Pyramid并非就一定要使用其提供的标准模板来搭建应用,比如下面的代码就建立了一个带2个页面的简单web应用:
python helloworld.py
系统将出现如下提示信息:
serving on 0.0.0.0:8080 view at http://127.0.0.1:8080
这就说明一个web应用已经在本机8080端口提供服务了。现在我们就可以用http://127.0.0.1:8080和http://127.0.0.1:8080/goodbye访问这两个页面了。
(注意,这里需要事先将pyramid安装好,如果使用了虚拟环境,需要先启动虚拟环境)
下面我们逐行看一下这些代码的含义。
首先,看这两个函数的定义:
def hello_world(request):
return Response(’Hello world!’)
def goodbye_world(request):
return Response(’Goodbye world!’)
这两个函数均接收一个request参数,并组织一个Response对象返回。在Pyramid中,这样的函数就叫做可调用视图。它接收的request参数就是由WSGI 服务器传递给Pyramid的一个HTTP请求。
可调用视图必须返回一个Response对象以构建一个真实的HTTP 应答。该对象将会在WSGI 服务器转换成文本并发送给浏览器。
因此,上述两个函数基本上可以看着两个页面内容的具体实现。
接下来,我们再看
config = Configurator()
这一行创建了一个Configurator对象的示例。该对象就是本代码段用来进行Pyramid配置的一个接口。使用该对象提供的方法,我们可以改变这个小应用中的应用注册器中的包含的注册项。
接下来,马上可以看到我们怎么将一个可调用视图注册到本应用的配置对象中。
config.add_view(hello_world)
config.add_view(goodbye_world, name=’goodbye’)
在这里,hello_world, goodbye_world就是前面定义的可调用视图。我们通过add_view这个方法,就可以将这两个视图与对应的调用url结构添加到配置对象中。在上面的例子中,name是一个可选的视图参数,代表了只有http请求中包含这个name的值的请求才会激活它对应的可调用视图,name默认值为‘’。
基于上面的这个定义,我们就可以用URL /来访问hello_world视图对应的内容,而用URL /goodbye访问goodbye_world视图对应的内容。
add_view的定义是无序的,当Pyramid处理一个请求时,将总是调用参数最匹配的那个配置。
最后的两行就是启动一个wsgi 服务器来提供服务。
app = config.make_wsgi_app()
serve(app, host=’0.0.0.0’)
一旦配置结束,我们就可以使用make_wsgi_app来创建一个wsgi应用对象。然后就可以将该对象传递给一个paster的HTTP服务器对外提供服务了。这里我们指定了host='0.0.0.0'表示任意IP地址均可以访问本服务,如果仅提供本机服务而不提供远程访问的话,可以将host赋值成'127.0.0.1'。paster HTTP服务器默认采用8080端口提供服务。
本文提到的示例材料均源于Pyramid官方网站
from pyramid.config import Configurator from pyramid.response import Response from paste.httpserver import serve def hello_world(request): return Response(’Hello world!’) def goodbye_world(request): return Response(’Goodbye world!’) if __name__ == ’__main__’: config = Configurator() config.add_view(hello_world) config.add_view(goodbye_world, name=’goodbye’) app = config.make_wsgi_app() serve(app, host=’0.0.0.0’)将上述代码保存为helloworld.py,然后在命令行运行:
python helloworld.py
系统将出现如下提示信息:
serving on 0.0.0.0:8080 view at http://127.0.0.1:8080
这就说明一个web应用已经在本机8080端口提供服务了。现在我们就可以用http://127.0.0.1:8080和http://127.0.0.1:8080/goodbye访问这两个页面了。
(注意,这里需要事先将pyramid安装好,如果使用了虚拟环境,需要先启动虚拟环境)
下面我们逐行看一下这些代码的含义。
首先,看这两个函数的定义:
def hello_world(request):
return Response(’Hello world!’)
def goodbye_world(request):
return Response(’Goodbye world!’)
这两个函数均接收一个request参数,并组织一个Response对象返回。在Pyramid中,这样的函数就叫做可调用视图。它接收的request参数就是由WSGI 服务器传递给Pyramid的一个HTTP请求。
可调用视图必须返回一个Response对象以构建一个真实的HTTP 应答。该对象将会在WSGI 服务器转换成文本并发送给浏览器。
因此,上述两个函数基本上可以看着两个页面内容的具体实现。
接下来,我们再看
config = Configurator()
这一行创建了一个Configurator对象的示例。该对象就是本代码段用来进行Pyramid配置的一个接口。使用该对象提供的方法,我们可以改变这个小应用中的应用注册器中的包含的注册项。
接下来,马上可以看到我们怎么将一个可调用视图注册到本应用的配置对象中。
config.add_view(hello_world)
config.add_view(goodbye_world, name=’goodbye’)
在这里,hello_world, goodbye_world就是前面定义的可调用视图。我们通过add_view这个方法,就可以将这两个视图与对应的调用url结构添加到配置对象中。在上面的例子中,name是一个可选的视图参数,代表了只有http请求中包含这个name的值的请求才会激活它对应的可调用视图,name默认值为‘’。
基于上面的这个定义,我们就可以用URL /来访问hello_world视图对应的内容,而用URL /goodbye访问goodbye_world视图对应的内容。
add_view的定义是无序的,当Pyramid处理一个请求时,将总是调用参数最匹配的那个配置。
最后的两行就是启动一个wsgi 服务器来提供服务。
app = config.make_wsgi_app()
serve(app, host=’0.0.0.0’)
一旦配置结束,我们就可以使用make_wsgi_app来创建一个wsgi应用对象。然后就可以将该对象传递给一个paster的HTTP服务器对外提供服务了。这里我们指定了host='0.0.0.0'表示任意IP地址均可以访问本服务,如果仅提供本机服务而不提供远程访问的话,可以将host赋值成'127.0.0.1'。paster HTTP服务器默认采用8080端口提供服务。
本文提到的示例材料均源于Pyramid官方网站
pyramid 1.1 简单试用
测试操作系统:Ubuntu 10.10
首先下载一个virtualenv,拉出其中的virtualenv.py,运行
python virtualenv.py pyramid-1.1
建立一个虚拟的python工作环境。
然后,运行source pyramid-1.1/bin/activate激活该虚拟环境。
再输入命令easy_install pyramid 即可完成安装。
很简单的安装过程,跟以前的pylons基本相同。
先拷贝一个官网的小例子测似一下
编辑保存成test.py。
运行python test.py
浏览器查看http://127.0.0.1:8080没有问题。
再来创建一个小项目试试看,
paster create -t pyramid_starter
这里pyramid_starter是pyramid中内置的一个项目模板
再运行
python setup.py develop
初始化这个项目的开发环境
然后运行
paster serve development.ini
即可启动这个小项目。
这里跟以前的pylons不同的地方就是多了一个python setup.py develop步骤,需要注意一下。
更详细的pyramid使用还是摸索中,
首先下载一个virtualenv,拉出其中的virtualenv.py,运行
python virtualenv.py pyramid-1.1
建立一个虚拟的python工作环境。
然后,运行source pyramid-1.1/bin/activate激活该虚拟环境。
再输入命令easy_install pyramid 即可完成安装。
很简单的安装过程,跟以前的pylons基本相同。
先拷贝一个官网的小例子测似一下
from paste.httpserver import serve from pyramid.config import Configurator from pyramid.response import Response def hello_world(request): return Response('Hello world!') if __name__ == '__main__': config = Configurator() config.add_view(hello_world) app = config.make_wsgi_app() serve(app, host='0.0.0.0')
编辑保存成test.py。
运行python test.py
浏览器查看http://127.0.0.1:8080没有问题。
再来创建一个小项目试试看,
paster create -t pyramid_starter
这里pyramid_starter是pyramid中内置的一个项目模板
再运行
python setup.py develop
初始化这个项目的开发环境
然后运行
paster serve development.ini
即可启动这个小项目。
这里跟以前的pylons不同的地方就是多了一个python setup.py develop步骤,需要注意一下。
更详细的pyramid使用还是摸索中,
Sunday, July 24, 2011
Pyramid 1.1 正式发布了。
Pyramid是一个非常通用的开源Python Web 框架。它的主要目标是让开发人员可以很方便的创建诸如电子表格、企业内网或WEB 2.0的社交网站等任意Web项目。
Pyramid的开发遵循以下宗旨:
* 简明
Pyramid基于“pay only for what you eat”的理念构建,即开发人员只需要了解部分Pyramid知识便可完成相应的工作,创建一个应用也无需任何特定的技术。Pyramid努力保证开发人员仅需了解一个最小的核心理念集即可。
* 扼要
Pyramid关注于为Web应用开发所面临的URL映射、模板、安全、静态资源使用等基本问题提供快速、高质量的解决方案。
* 文档
Pyramid提供即时详尽的文档。
* 速度
Pyramid为模板化、应答生成等WEB共性任务提供显著的执行速度。
* 可靠
Pyramid的源码管理箴言是“无测即无效”。Pyramid任何发行版本将提供100%的单元测试覆盖率。
* 开放
Pyramid采用宽松的许可协议。
本次1.1版本发布主要变更包括:
1. 术语变更
Paster模板将统一改称scaffolds,而用于页面渲染的模板仍沿用templates的叫法。(Pyramid这次总算舍得将这两模板区分开了。。。)
2. 主要功能点
* pyramid.request.Request类增加了response属性
* 增加了paster pviews命令可以查看匹配的view
* 支持“静态”路由,add_route增加了一个static参数(这个静态好像定义的不太准确。)
* 支持缺省的HTTP异常视图
* 可以通过http_cache设置HTTP caching headers
* 提供了bootstrap接口可以为在Pyramid环境下编写脚本提供方便
需要注意的是Pyramid将不再支持Python 2.4及更低版本,也不支持Python 3的任何版本。
看来可以找个项目导入试试看了。
Pyramid的开发遵循以下宗旨:
* 简明
Pyramid基于“pay only for what you eat”的理念构建,即开发人员只需要了解部分Pyramid知识便可完成相应的工作,创建一个应用也无需任何特定的技术。Pyramid努力保证开发人员仅需了解一个最小的核心理念集即可。
* 扼要
Pyramid关注于为Web应用开发所面临的URL映射、模板、安全、静态资源使用等基本问题提供快速、高质量的解决方案。
* 文档
Pyramid提供即时详尽的文档。
* 速度
Pyramid为模板化、应答生成等WEB共性任务提供显著的执行速度。
* 可靠
Pyramid的源码管理箴言是“无测即无效”。Pyramid任何发行版本将提供100%的单元测试覆盖率。
* 开放
Pyramid采用宽松的许可协议。
本次1.1版本发布主要变更包括:
1. 术语变更
Paster模板将统一改称scaffolds,而用于页面渲染的模板仍沿用templates的叫法。(Pyramid这次总算舍得将这两模板区分开了。。。)
2. 主要功能点
* pyramid.request.Request类增加了response属性
* 增加了paster pviews命令可以查看匹配的view
* 支持“静态”路由,add_route增加了一个static参数(这个静态好像定义的不太准确。)
* 支持缺省的HTTP异常视图
* 可以通过http_cache设置HTTP caching headers
* 提供了bootstrap接口可以为在Pyramid环境下编写脚本提供方便
需要注意的是Pyramid将不再支持Python 2.4及更低版本,也不支持Python 3的任何版本。
看来可以找个项目导入试试看了。
Monday, April 11, 2011
compressed RotatingFileHandler for python
class CompressedRotatingFileHandler(RotatingFileHandler): def __init__(self, filename, mode='a', maxBytes=0, backupCount=0, encoding=None, delay=0): RotatingFileHandler.__init__(self, filename, mode, maxBytes, backupCount, encoding, delay) def doRollover(self): self.stream.close() if self.backupCount > 0: for i in range(self.backupCount - 1, 0, -1): sfn = "%s.%d.gz" % (self.baseFilename, i) dfn = "%s.%d.gz" % (self.baseFilename, i + 1) if os.path.exists(sfn): #print "%s -> %s" % (sfn, dfn) if os.path.exists(dfn): os.remove(dfn) os.rename(sfn, dfn) dfn = self.baseFilename + ".1.gz" if os.path.exists(dfn): os.remove(dfn) import gzip try: f_in = open(self.baseFilename, 'rb') f_out = gzip.open(dfn, 'wb') f_out.writelines(f_in) except: if not os.path.exists(dfn): if os.path.exists(self.baseFilename): os.rename(self.baseFilename, dfn) finally: if "f_out" in dir() and f_out is not None: f_out.close() if "f_in" in dir() and f_in is not None: f_in.close() if os.path.exists(self.baseFilename): os.remove(self.baseFilename) #os.rename(self.baseFilename, dfn) #print "%s -> %s" % (self.baseFilename, dfn) self.mode = 'w' self.stream = self._open()
Friday, April 1, 2011
other thread pool options used in pylons configuration
[server:main]
use = egg:Paste#http
host = 127.0.0.1:8081
# These options make it easier to trigger the thread pool catches
# (i.e., threads are hung fast, killed fast, spawn fast, and the
# whole process dies quickly due to zombies)
threadpool_workers = 3
threadpool_hung_thread_limit = 10
threadpool_kill_thread_limit = 20
threadpool_spawn_if_under = 2
threadpool_max_zombie_threads_before_die = 2
threadpool_hung_check_period = 1
threadpool_dying_limit = 10
use = egg:Paste#http
host = 127.0.0.1:8081
# These options make it easier to trigger the thread pool catches
# (i.e., threads are hung fast, killed fast, spawn fast, and the
# whole process dies quickly due to zombies)
threadpool_workers = 3
threadpool_hung_thread_limit = 10
threadpool_kill_thread_limit = 20
threadpool_spawn_if_under = 2
threadpool_max_zombie_threads_before_die = 2
threadpool_hung_check_period = 1
threadpool_dying_limit = 10
extend default thread pool workers of paster in pylons
add a option named threadpool_workers in server:main section in development.ini as below:
[server:main]
use = egg:Paste#http
host = 127.0.0.1
port = 5000
threadpool_workers = 20
then you will get this message from log:
11:09:33,678 INFO [paste.httpserver.ThreadPool] kill_hung_threads status: 20 threads (0 working, 20 idle, 0 starting) ave time N/A, max time 0.00sec, killed 0 workers
[server:main]
use = egg:Paste#http
host = 127.0.0.1
port = 5000
threadpool_workers = 20
then you will get this message from log:
11:09:33,678 INFO [paste.httpserver.ThreadPool] kill_hung_threads status: 20 threads (0 working, 20 idle, 0 starting) ave time N/A, max time 0.00sec, killed 0 workers
Subscribe to:
Posts (Atom)