Size: 7362
Comment:
|
← Revision 15 as of 2009-12-25 07:11:09 ⇥
Size: 8120
Comment: converted to 1.6 markup
|
Deletions are marked like this. | Additions are marked like this. |
Line 1: | Line 1: |
=Pylons Support for the Web Server Gateway Interface= | ## page was renamed from PyLons/wsgi = PyLons 对 WEB服务网关接口(WSGI)的支持 = :author: James Gardner |
Line 3: | Line 5: |
:date: 2006-07-23 | |
Line 4: | Line 7: |
:author: James Gardner :date: 2006-07-23 |
:译者: xlp223 |
Line 9: | Line 12: |
尽管大多数python frameworks都允许它们的应用都作为WSGI应用来运行,而pylons 0.9 WSGI集成度更高,在全部堆栈中支持WSGI。可以预见,随着其他framework支持wsgi,我们将看到在python web开发中进入崭新的阶段。 | 尽管大多数python frameworks都允许它们的应用都作为WSGI应用来运行,而PyLons 0.9 WSGI集成度更高,在全部堆栈中支持WSGI。可以预见,随着其他framework支持wsgi,我们将看到在python web开发中进入崭新的阶段。 |
Line 13: | Line 16: |
这篇指南会给你一个基本知识,教你在pylons怎样使用WSGI application和middleware. | 这篇指南会给你一个基本知识,教你在PyLons怎样使用WSGI application和middleware. |
Line 15: | Line 18: |
Paste and WSGI ============== |
== Paste and WSGI == 大部分PyLons的WSGI的能力得益于它紧密集成的Paste。Paste提供了相当多,而且必要的工具和middleware来部署WSGI application。它可以被看作一个相当底层的WSGI framework,它是为其他构建其上的web framework而设计的,PyLons只是完全利用paste的其中一个framework。 |
Line 18: | Line 21: |
大部分pylons的WSGI的能力得益于它紧密集成的Paste。Paste提供了相当多,而且必要的工具和middleware来部署WSGI application。它可以被看作一个相当底层的WSGI framework,它是为其他构建其上的web framework而设计的,pylons只是完全利用paste的其中一个framework。 | 如果你想,你可以从你的PyLons配置文件中得到WSGI application 对象。比如: |
Line 20: | Line 23: |
如果你想,你可以从你的pylons配置文件中得到WSGI application 对象。比如: .. code-block:: Python from paste.deploy import loadapp wsgi_app = loadapp('config:/path/to/config.ini') |
{{{#!python from paste.deploy import loadapp wsgi_app = loadapp('config:/path/to/config.ini') }}} |
Line 29: | Line 28: |
.. code-block:: Python | |
Line 31: | Line 29: |
from paste.deploy import loadapp wsgi_app = loadapp('config:/path/to/config.ini') from wsgiref import simple_server httpd = simple_server.WSGIServer(('',8000), simple_server.WSGIRequestHandler) httpd.set_app(wsgi_app) httpd.serve_forever() |
{{{#!python from paste.deploy import loadapp wsgi_app = loadapp('config:/path/to/config.ini') |
Line 39: | Line 33: |
在pylons项目的开发中你可以使用``paster serve``命令来合并上面的两步,从配置文件创建一个WSGI app,并可以直接使用这个配置文件从而启动服务。 因为启动的pylons应用是一个WSGI application,就意味着你可以像处理WSGI application一样来做同样的事情。举个例子,给它加一个middleware chain或者通过fastcgi/scgi/cgi/mod_python/ajp来启动服务或者单独运行。 |
from wsgiref import simple_server httpd = simple_server.WSGIServer(('',8000), simple_server.WSGIRequestHandler) httpd.set_app(wsgi_app) httpd.serve_forever() }}} |
Line 43: | Line 39: |
你也可以配置额外的WSGI middleware,application和更多直接使用的配置文件。更多不同的选项,你可以从`Paste Deploy Documentation <http://pythonpaste.org/deploy/>`_看到,这里我们就不重复了。 | 在PyLons项目的开发中你可以使用{{{}}}paster serve{{{}}}命令来合并上面的两步,从配置文件创建一个WSGI app,并可以直接使用这个配置文件从而启动服务。 |
Line 45: | Line 41: |
Using a WSGI Application as a Pylons 0.9 Controller --------------------------------------------------- |
因为启动的PyLons应用是一个WSGI application,就意味着你可以像处理WSGI application一样来做同样的事情。举个例子,给它加一个middleware chain或者通过fastcgi/scgi/cgi/mod_python/ajp来启动服务或者单独运行。 |
Line 48: | Line 43: |
在pylons 0.9 controllers是从``pylons.controllers.WSGIController``派生而来,并且也是一个有效的WSGI application。除非你的controller是从以前的``pylons.controllers.Controller``派生得来,它也是被假定是一个WSGI application。这就是说你不必在你的controller中使用一个Pylons controller,只要你给它同一个名字,任何WSGI application都能起作用。 | 你也可以配置额外的WSGI middleware,application和更多直接使用的配置文件。更多不同的选项,你可以从{{{Paste Deploy Documentation <http://pythonpaste.org/deploy/>}}}_看到,这里我们就不重复了。 |
Line 50: | Line 45: |
举例来说,假如你用``paster controller hello``命令加了一个``hello`` controller,你可以改变它: | |
Line 52: | Line 46: |
.. code-block:: Python | |
Line 54: | Line 47: |
def HelloController(environ, start_response): start_response('200 OK', [('Content-Type','text/html')]) return ['Hello World!'] |
== Using a WSGI Application as a PyLons 0.9 Controller == |
Line 58: | Line 49: |
或者使用``yield``语句: | 在PyLons 0.9 controllers是从PyLons.controllers.WSGIController派生而来,并且也是一个有效的WSGI application。除非你的controller是从以前的PyLons.controllers.Controller派生得来,它也是被假定是一个WSGI application。这就是说你不必在你的controller中使用一个PyLons controller,只要你给它同一个名字,任何WSGI application都能起作用。举例来说,假如你用{{{}}}paster controller hello{{{}}}命令加了一个{{{}}}hello{{{}}} controller,你可以改变它: |
Line 60: | Line 51: |
.. code-block:: Python | {{{#!python def HelloController(environ, start_response): start_response('200 OK', [('Content-Type','text/html')]) return ['Hello World!'] }}} |
Line 62: | Line 57: |
def HelloController(environ, start_response): start_response('200 OK', [('Content-Type','text/html')]) yield 'Hello ' yield 'World!' |
或者使用{{{}}}yield{{{}}}语句: |
Line 67: | Line 59: |
或者使用标准的pylons ``Response`` 对象,它也是一个有效的WSGI response,和调用``start_response``有关的。 | {{{#!python def HelloController(environ, start_response): start_response('200 OK', [('Content-Type','text/html')]) yield 'Hello ' yield 'World!' }}} |
Line 69: | Line 66: |
.. code-block:: Python | 或者使用标准的PyLons {{{}}}Response{{{}}} 对象,它也是一个有效的WSGI response,和调用{{{}}}start_response{{{}}}有关的。 |
Line 71: | Line 68: |
def HelloController(environ, start_response): return Response('Hello World!') |
{{{#!python def HelloController(environ, start_response): return Response('Hello World!') }}} |
Line 74: | Line 73: |
你还可以使用``render()``和``render_response()``,像你在一个通常的controller action里一样。 | 你还可以使用{{{}}}render(){{{}}}和{{{}}}render_response(){{{}}},像你在一个通常的controller action里一样。 |
Line 78: | Line 77: |
.. code-block:: Python | {{{#!python class HelloController: def __call__(self, environ, start_response): start_response('200 OK', [('Content-Type','text/html')]) return ['Hello World!'] }}} |
Line 80: | Line 84: |
class HelloController: def __call__(self, environ, start_response): start_response('200 OK', [('Content-Type','text/html')]) return ['Hello World!'] |
所有在config/middleware.py中定义的标准PyLons middleware依然还是有用的。 |
Line 85: | Line 86: |
所有在``config/middleware.py``中定义的标准pylons middleware依然还是有用的。 | == Running a WSGI Application From Within a Controller == |
Line 87: | Line 88: |
Running a WSGI Application From Within a Controller --------------------------------------------------- |
很多情况你不想用一个WSGI application来替换你的完整controller,只想简单地从一个controller action运行一个WSGI application。如果你的project被称为{{{}}}test{{{}}},你有一个WSGI application {{{}}}wsgi_app{{{}}},你可以这样做: |
Line 90: | Line 90: |
很多情况你不想用一个WSGI application来替换你的完整controller,只想简单地从一个controller action运行一个WSGI application。如果你的project被称为``test``,你有一个WSGI application ``wsgi_app``,你可以这样做: | {{{#!python from test.lib.base import * def wsgi_app(environ, start_response): start_response('200 OK',[('Content-type','text/html')]) return ['<html>\n<body>\nHello World!\n</body>\n</html>'] class HelloController(BaseController): def index(self): return wsgi_app(request.environ, self.start_response) }}} |
Line 92: | Line 101: |
.. code-block:: Python | == Configuring Middleware Within a PyLons Application == |
Line 94: | Line 103: |
from test.lib.base import * | 一个PyLons applcation的middleware堆栈是直接写在项目的{{{}}}config/middleware.py{{{}}}文件中。也就是说你可以从堆栈中增加和移除你选择的部分。 |
Line 96: | Line 105: |
def wsgi_app(environ, start_response): start_response('200 OK',[('Content-type','text/html')]) return ['<html>\n<body>\nHello World!\n</body>\n</html>'] class HelloController(BaseController): def index(self): return wsgi_app(request.environ, self.start_response) Configuring Middleware Within a Pylons Application -------------------------------------------------- 一个pylons applcation的middleware堆栈是直接写在项目的``config/middleware.py``文件中。也就是说你可以从堆栈中增加和移除你选择的部分。 .. Warning:: 如果移除掉缺省的middleware,你将会发现pylons不能正常运转了! |
.. Warning:: 如果移除掉缺省的middleware,你将会发现PyLons不能正常运转了! |
Line 113: | Line 109: |
.. code-block:: Python | {{{#!python |
Line 115: | Line 111: |
# YOUR MIDDLEWARE # Put your own middleware here, so that any problems are caught by the error # handling middleware underneath class KeyAdder: def __init__(self, app, key, value): self.app = app if '.' not in key: raise Exception("WSGI environ keys must contain a '.' character") self.key = key self.value = value def __call__(self, environ, start_response): environ[key] = value return self.app(environ, start_response) app = KeyAdder(app, 'test.hello', 'Hello World') |
# YOUR MIDDLEWARE # Put your own middleware here, so that any problems are caught by the error # handling middleware underneath class KeyAdder: def __init__(self, app, key, value): self.app = app if '.' not in key: raise Exception("WSGI environ keys must contain a '.' character") self.key = key self.value = value def __call__(self, environ, start_response): environ[key] = value return self.app(environ, start_response) app = KeyAdder(app, 'test.hello', 'Hello World') }}} |
Line 135: | Line 128: |
.. code-block:: Python | {{{#!python return Response(request.environ['test.hello']) }}} |
Line 137: | Line 132: |
return Response(request.environ['test.hello']) 你可以看到``Hello World!``信息了。 |
你可以看到{{{}}}Hello World!{{{}}}信息了。 |
Line 143: | Line 136: |
*改变environ字典 *改变状态 *改变HTTP头信息 *改变application的response body |
* 改变environ字典 * 改变状态 * 改变HTTP头信息 * 改变application的response body 因为作为middleware可以做以上的事,你就可以创建authentication代码,错误处理等等,但是WSGI更有意义的是可能已经有人做好了相关的组件了。具体的你可以参见 {{{wsgi.org middleware list <http://wsgi.org/wsgi/Middleware_and_Utilities>}}}_ 或{{{Paste project <http://pythonpaste.org>}}}_,重用已经存在的middleware。 |
Line 148: | Line 142: |
因为作为middleware可以做以上的事,你就可以创建authentication代码,错误处理等等,但是WSGI更有意义的是可能已经有人做好了相关的组件了。具体的你可以参见 `wsgi.org middleware list <http://wsgi.org/wsgi/Middleware_and_Utilities>`_ 或`Paste project <http://pythonpaste.org>`_,重用已经存在的middleware。 | |
Line 150: | Line 143: |
The Cascade ----------- |
|
Line 153: | Line 144: |
在你的project中的``config/middleware.py``文件,middleware堆栈的最后,你可以发现其中的一个片断叫cascade: | == The Cascade == |
Line 155: | Line 146: |
.. code-block:: Python # @@@ Cascade @@@ app = Cascade([static_app, javascripts_app, app]) 传入application的一个列表,``Cascade``将会按顺序执行。如果有一个返回404状态码, |
在你的project中的{{{}}}config/middleware.py{{{}}}文件,middleware堆栈的最后,你可以发现其中的一个片断叫cascade: {{{#!python # @@@ Cascade @@@ app = Cascade([static_app, javascripts_app, app]) }}} 传入application的一个列表,{{{}}}Cascade{{{}}}将会按顺序执行。如果有一个返回404状态码,那么下一个application就会试着执行,直到有一个application返回一个代码``200``,表示有应答。如果所有的application都失败,那会出现最后一个application的失败响应。 cascade的文件有3个WSGI application,先从你的project的``public``目录开始,如果没有匹配的,就搜索WebHelper的javascript模块,最后如果没有javascript,你的PyLons app就开始执行了。这就是为什么``public/index.html``文件在你的controller执行之前被响应,以及为什么在你的HTML中放入``/javascripts/``,相关的文件会找到。 你可以自由地改变cascade的顺序,或者在``app``之前加入额外的WSGI application,以便在你的PyLons application执行之前可以找到它的位置。 == Summary == 当其他frameworks把WSGI适配器加入到堆栈中,以便它们的应用可以在WSGI server下使用,我们希望你能了解,PyLons是怎样通过它的设计来拥抱WSGI的,使之成为最具灵活性和扩展性的python web framework。 |
PyLons 对 WEB服务网关接口(WSGI)的支持
:author: James Gardner
:date: 2006-07-23
:译者: xlp223
Web Server Gateway Interface(WSGI)是python社区公认的规范,它旨在使得python frameworks,middleware和server之间互操作性成为可能。
尽管大多数python frameworks都允许它们的应用都作为WSGI应用来运行,而PyLons 0.9 WSGI集成度更高,在全部堆栈中支持WSGI。可以预见,随着其他framework支持wsgi,我们将看到在python web开发中进入崭新的阶段。
WSGI的规则实际上非常简单,但是要解释清楚确是相当困难。要了解全部的相关信息,你要去http://www.python.org/peps/ppp-0333.html看pep 333。
这篇指南会给你一个基本知识,教你在PyLons怎样使用WSGI application和middleware.
Paste and WSGI
大部分PyLons的WSGI的能力得益于它紧密集成的Paste。Paste提供了相当多,而且必要的工具和middleware来部署WSGI application。它可以被看作一个相当底层的WSGI framework,它是为其他构建其上的web framework而设计的,PyLons只是完全利用paste的其中一个framework。
如果你想,你可以从你的PyLons配置文件中得到WSGI application 对象。比如:
1 from paste.deploy import loadapp wsgi_app = loadapp('config:/path/to/config.ini')
然后你使用一个WSGI server来启动这个文件的服务。这是一个使用包含在python 2.5中的wsgiref实现的一段代码:
在PyLons项目的开发中你可以使用paster serve命令来合并上面的两步,从配置文件创建一个WSGI app,并可以直接使用这个配置文件从而启动服务。
因为启动的PyLons应用是一个WSGI application,就意味着你可以像处理WSGI application一样来做同样的事情。举个例子,给它加一个middleware chain或者通过fastcgi/scgi/cgi/mod_python/ajp来启动服务或者单独运行。
你也可以配置额外的WSGI middleware,application和更多直接使用的配置文件。更多不同的选项,你可以从Paste Deploy Documentation <http://pythonpaste.org/deploy/>_看到,这里我们就不重复了。
Using a WSGI Application as a PyLons 0.9 Controller
在PyLons 0.9 controllers是从PyLons.controllers.WSGIController派生而来,并且也是一个有效的WSGI application。除非你的controller是从以前的PyLons.controllers.Controller派生得来,它也是被假定是一个WSGI application。这就是说你不必在你的controller中使用一个PyLons controller,只要你给它同一个名字,任何WSGI application都能起作用。举例来说,假如你用paster controller hello命令加了一个hello controller,你可以改变它:
或者使用yield语句:
或者使用标准的PyLons Response 对象,它也是一个有效的WSGI response,和调用start_response有关的。
你还可以使用render()和render_response(),像你在一个通常的controller action里一样。
你也可以在一个class中像写一个function一样来写你的WSGI application。
所有在config/middleware.py中定义的标准PyLons middleware依然还是有用的。
Running a WSGI Application From Within a Controller
很多情况你不想用一个WSGI application来替换你的完整controller,只想简单地从一个controller action运行一个WSGI application。如果你的project被称为test,你有一个WSGI application wsgi_app,你可以这样做:
1 from test.lib.base import *
2 def wsgi_app(environ, start_response):
3 start_response('200 OK',[('Content-type','text/html')])
4 return ['<html>\n<body>\nHello World!\n</body>\n</html>']
5
6 class HelloController(BaseController):
7 def index(self):
8 return wsgi_app(request.environ, self.start_response)
Configuring Middleware Within a PyLons Application
一个PyLons applcation的middleware堆栈是直接写在项目的config/middleware.py文件中。也就是说你可以从堆栈中增加和移除你选择的部分。
.. Warning:: 如果移除掉缺省的middleware,你将会发现PyLons不能正常运转了!
比如,如果你想加一个middleware,它是用来给environ字典中加一个新关键字:
1 # YOUR MIDDLEWARE
2 # Put your own middleware here, so that any problems are caught by the error
3 # handling middleware underneath
4 class KeyAdder:
5 def __init__(self, app, key, value):
6 self.app = app if '.' not in key:
7 raise Exception("WSGI environ keys must contain a '.' character")
8 self.key = key
9 self.value = value
10 def __call__(self, environ, start_response):
11 environ[key] = value
12 return self.app(environ, start_response)
13 app = KeyAdder(app, 'test.hello', 'Hello World')
然后在你的controller:
1 return Response(request.environ['test.hello'])
你可以看到Hello World!信息了。
当然,这不是特别有用的东西。middleware类可以做四样事中一样或多样:
- 改变environ字典
- 改变状态
- 改变HTTP头信息
- 改变application的response body
因为作为middleware可以做以上的事,你就可以创建authentication代码,错误处理等等,但是WSGI更有意义的是可能已经有人做好了相关的组件了。具体的你可以参见 wsgi.org middleware list <http://wsgi.org/wsgi/Middleware_and_Utilities>_ 或Paste project <http://pythonpaste.org>_,重用已经存在的middleware。
The Cascade
在你的project中的config/middleware.py文件,middleware堆栈的最后,你可以发现其中的一个片断叫cascade:
传入application的一个列表,Cascade将会按顺序执行。如果有一个返回404状态码,那么下一个application就会试着执行,直到有一个application返回一个代码200,表示有应答。如果所有的application都失败,那会出现最后一个application的失败响应。
cascade的文件有3个WSGI application,先从你的project的public目录开始,如果没有匹配的,就搜索WebHelper的javascript模块,最后如果没有javascript,你的PyLons app就开始执行了。这就是为什么public/index.html文件在你的controller执行之前被响应,以及为什么在你的HTML中放入/javascripts/,相关的文件会找到。
你可以自由地改变cascade的顺序,或者在app之前加入额外的WSGI application,以便在你的PyLons application执行之前可以找到它的位置。
Summary
当其他frameworks把WSGI适配器加入到堆栈中,以便它们的应用可以在WSGI server下使用,我们希望你能了解,PyLons是怎样通过它的设计来拥抱WSGI的,使之成为最具灵活性和扩展性的python web framework。