WSGI的问题集

12 views
Skip to first unread message

limodou

unread,
Dec 24, 2008, 9:59:04 PM12/24/08
to Python.cn@google
希望对wsgi了解的介绍下:

1. WSGI的app之间如何传递消息?在environ中添加吗?

2. 多个app之间通过wsgi方式来工作,一般是怎么被调用的?它们的调用如何实现配置化?

3. 对于request, response这样的东西如何在wsgi中处理,如何传递?是每次通过environ直接生成吗?如:

request = Request(environ)

这样做,会不会有效率问题。另外如何处理request中动态添加的属性,丢失吗?

先想这么多。

--
I like python!
UliPad <<The Python Editor>>: http://code.google.com/p/ulipad/
UliWeb <<simple web framework>>: http://uliwebproject.appspot.com
My Blog: (new)http://http://hi.baidu.com/limodou
(old)http://www.donews.net/limodou

Zoom.Quiet

unread,
Dec 24, 2008, 10:08:10 PM12/24/08
to pyth...@googlegroups.com
2008/12/25 limodou <lim...@gmail.com>:

> 希望对wsgi了解的介绍下:
>
> 1. WSGI的app之间如何传递消息?在environ中添加吗?
>
> 2. 多个app之间通过wsgi方式来工作,一般是怎么被调用的?它们的调用如何实现配置化?
>
> 3. 对于request, response这样的东西如何在wsgi中处理,如何传递?是每次通过environ直接生成吗?如:
>
> request = Request(environ)
>
> 这样做,会不会有效率问题。另外如何处理request中动态添加的属性,丢失吗?
>
共同学习:
理解WSGI:
- PEP 333 -- Python Web Server Gateway Interface v1.0
http://www.python.org/dev/peps/pep-0333/
- WSGI-Gateway or Glue? - 动态感觉 静观其变 - 歪酷博客 Ycool Blog
http://xlp223.ycool.com/post.1639120.html
实用WSGI:
- 用 Python WSGI 混和并匹配 Web 组件
http://www-128.ibm.com/developerworks/cn/web/wa-wsgi/index.html
- PyLons 对 WEB服务网关接口(WSGI)的支持
http://wiki.woodpecker.org.cn/moin/PyLons/wsgi
WSGI框架:
- Frameworks - WSGI Wiki
http://www.wsgi.org/wsgi/Frameworks
- A Pylons controller with MoinMoin as a WSGI callable - Pylons
Cookbook - PythonWeb
http://wiki.pylonshq.com/display/pylonscookbook/A+Pylons+controller+with+MoinMoin+as+a+WSGI+callable
- WsgiRequestPatch - MoinMoin
http://moinmoin.wikiwikiweb.de/WsgiRequestPatch
> 先想这么多。
>

--
http://zoomquiet.org
'''过程改进乃是催生可促生靠谱的人的组织!'''
Usage OOo to replace M$ Office; You can get the truely Freedom 4 software.

limodou

unread,
Dec 24, 2008, 10:54:19 PM12/24/08
to pyth...@googlegroups.com
2008/12/25 Zoom. Quiet <zoom....@gmail.com>:

有没有直接回答的嘛?

我又看了看xlp223的blog,理解了以下内容:

1. wsgi app之间的调用象这样

def configure(app):
return ErrorHandlerMiddleware(
SessionMiddleware(
IdentificationMiddleware(
AuthenticationMiddleware(
UrlParserMiddleware(app))))))

因此出现了paster,在每个app程序中添加:

def app_factory(global_config, **local_config):
return application

然后通过paster来管理这些app的执行顺序。这样每个app还可以有自已的配置参数。这样就可以理解为什么tg和pylons要使用paster了。不过对我来说的确是理解复杂。甚至象pkg_resources的使用也是最近才一点点理解并开始使用的。

这基本上回答了我的第2个问题。

对于第1个我估计还是在environ中设置的。

对于第三个问题,可能就与具体的框架相关了。目前不管是django也好,还是uliweb也好,其本上只有一个主wsgi应用在运行。不过因为uliweb的主要处理就是一个wsgi的app,所以是可以放在wsgi中进行使用的。

Qiangning Hong

unread,
Dec 24, 2008, 11:02:31 PM12/24/08
to pyth...@googlegroups.com
2008/12/25 limodou <lim...@gmail.com>:
> 希望对wsgi了解的介绍下:
>
> 1. WSGI的app之间如何传递消息?在environ中添加吗?

WSGI的处理模式为 WSGI Server -> (WSGI Middleware)* -> WSGI Application
,一次请求只有一个app。middleware和app之间通过environ交换消息。

> 2. 多个app之间通过wsgi方式来工作,一般是怎么被调用的?它们的调用如何实现配置化?

同上,一个request最终落到一个app上。不过每一个middleware对于调用者而言,接口和app是一样的。一般在前端有一个app
dispatcher通过URL选择执行哪一个app,可以是直接在WSGI
Server里的代码指定,也可以这个dispatcher本身就是一个middleware。Pylons使用的Routes这两种方式都支持。WSGI有一个route标准的草案。

Paste Deploy通过ini文件配置middleware的调用和初始化参数。

> 3. 对于request, response这样的东西如何在wsgi中处理,如何传递?是每次通过environ直接生成吗?如:
> request = Request(environ)

是的,webob其实就是怎么干的。

> 这样做,会不会有效率问题。另外如何处理request中动态添加的属性,丢失吗?

webob好像是用的lazy方式,初始化一个对象很轻量。如果要考虑效率问题,可以把生成的request对象也放在environ里面,之后的middleware和app就都可以直接使用了。Pylons是这样做的。

>
> 先想这么多。

--
Qiangning Hong
http://www.douban.com/people/hongqn/

YoungKing

unread,
Dec 24, 2008, 11:03:33 PM12/24/08
to pyth...@googlegroups.com
1. 每个wsgi app是一个callable对象,传递两个参数,一个是environment ,一个是start_response 函数,start_response这个函数用来response,你在这里设置status和header,最后返回一个iterator(通常是字符串list)
 
 
3.在wsgi中,environment对应request,start_response对应response.envrionment中可以传任意python对象,这个比request方便多了.你可以修改envionment,把属性放到这里来


2008/12/25 limodou <lim...@gmail.com>



--
润普公司:zopen.cn
易度项目在线管理平台:everydo.com

Qiangning Hong

unread,
Dec 24, 2008, 11:04:59 PM12/24/08
to pyth...@googlegroups.com
2008/12/25 limodou <lim...@gmail.com>:

> 对于第三个问题,可能就与具体的框架相关了。目前不管是django也好,还是uliweb也好,其本上只有一个主wsgi应用在运行。不过因为uliweb的主要处理就是一个wsgi的app,所以是可以放在wsgi中进行使用的。

Pylons是每一个Controller就是一个WSGI app。通过Routes来dispatch到某一个特定的controller运行。

Gu Yingbo

unread,
Dec 24, 2008, 11:05:38 PM12/24/08
to pyth...@googlegroups.com


2008/12/25 limodou <lim...@gmail.com>

我认为wsgi的中间件倾向于做一些简单独立事情,每个中间件app 的依赖性比较低,
像werkzeug的DebuggedApplication这种风格就很好,一条语句就可以为一个wsgi应用添加一个调试界面。
我自己也就用中间件做一个请求的计时,sql语句调试开关这样简单的事情。

我觉得wsgi的最大好处是分离了服务器和应用的实现,写一个wsgi应用就有一大把的部署方式,自己可以根据需要选择合适的。

limodou

unread,
Dec 24, 2008, 11:17:57 PM12/24/08
to pyth...@googlegroups.com
2008/12/25 Qiangning Hong <hon...@gmail.com>:

谢谢,这下就清楚许多了。按上面的回答,uliweb中的是Dispatcher(类名都是这么起的),所以它本身是wsgi的。在uliweb的前段时间,还可以通过config.py来添加在执行Dispatcher前的wsgi序列,不过现在去了,因为修改了许多地方,加回来也很容易。因此我想uliweb会同时支持wsgi
middleware和django-like middleware。因为django-like
middleware更多是在针对request, response的处理,目标比较统一。

对于wsgi的互用,我提第4个问题:不同的wsgi
middleware在不同的项目中是如何互用的?是不是目前都是需要基于paster才可以?有共它的方式,还是根本不存在问题。

因为我看到paster是可以在创建wsgi
middleware时引入一些local_conf的,这个倒是可以继续用,自已写一个简单的装入器。其它的有没有类似要依赖于paster的东西呢?

Zoom.Quiet

unread,
Dec 24, 2008, 11:19:24 PM12/24/08
to pyth...@googlegroups.com
太高效率了吧,,, 俺就收集:
http://wiki.woodpecker.org.cn/moin/WSGI

2008/12/25 limodou <lim...@gmail.com>:


> 2008/12/25 Qiangning Hong <hon...@gmail.com>:
>> 2008/12/25 limodou <lim...@gmail.com>:
>>> 希望对wsgi了解的介绍下:
>>>
>>> 1. WSGI的app之间如何传递消息?在environ中添加吗?
>>
>> WSGI的处理模式为 WSGI Server -> (WSGI Middleware)* -> WSGI Application
>> ,一次请求只有一个app。middleware和app之间通过environ交换消息。
>>
>>> 2. 多个app之间通过wsgi方式来工作,一般是怎么被调用的?它们的调用如何实现配置化?
>>
>> 同上,一个request最终落到一个app上。不过每一个middleware对于调用者而言,接口和app是一样的。一般在前端有一个app
>> dispatcher通过URL选择执行哪一个app,可以是直接在WSGI
>> Server里的代码指定,也可以这个dispatcher本身就是一个middleware。Pylons使用的Routes这两种方式都支持。WSGI有一个route标准的草案。
>>
>> Paste Deploy通过ini文件配置middleware的调用和初始化参数。
>>
>>> 3. 对于request, response这样的东西如何在wsgi中处理,如何传递?是每次通过environ直接生成吗?如:
>>> request = Request(environ)
>>
>> 是的,webob其实就是怎么干的。
>>
>>> 这样做,会不会有效率问题。另外如何处理request中动态添加的属性,丢失吗?
>>
>> webob好像是用的lazy方式,初始化一个对象很轻量。如果要考虑效率问题,可以把生成的request对象也放在environ里面,之后的middleware和app就都可以直接使用了。Pylons是这样做的。
>>
>
> 谢谢,这下就清楚许多了。按上面的回答,uliweb中的是Dispatcher(类名都是这么起的),所以它本身是wsgi的。在uliweb的前段时间,还可以通过config.py来添加在执行Dispatcher前的wsgi序列,不过现在去了,因为修改了许多地方,加回来也很容易。因此我想uliweb会同时支持wsgi
> middleware和django-like middleware。因为django-like
> middleware更多是在针对request, response的处理,目标比较统一。
>
> 对于wsgi的互用,我提第4个问题:不同的wsgi
> middleware在不同的项目中是如何互用的?是不是目前都是需要基于paster才可以?有共它的方式,还是根本不存在问题。
>
> 因为我看到paster是可以在创建wsgi
> middleware时引入一些local_conf的,这个倒是可以继续用,自已写一个简单的装入器。其它的有没有类似要依赖于paster的东西呢?
>

--
http://zoomquiet.org
'''过程改进乃是催生可促生靠谱的人的组织!'''
金山常年招聘Py/C++人才! http://bit.ly/UoTV 简历直投俺就成;-)

limodou

unread,
Dec 24, 2008, 11:21:33 PM12/24/08
to pyth...@googlegroups.com
2008/12/25 YoungKing <yan...@gmail.com>:

> 1. 每个wsgi app是一个callable对象,传递两个参数,一个是environment ,一个是start_response
> 函数,start_response这个函数用来response,你在这里设置status和header,最后返回一个iterator(通常是字符串list)
>
>
> 3.在wsgi中,environment对应request,start_response对应response.envrionment中可以传任意python对象,这个比request方便多了.你可以修改envionment,把属性放到这里来

嗯,这是一种办法。

limodou

unread,
Dec 24, 2008, 11:23:12 PM12/24/08
to pyth...@googlegroups.com
2008/12/25 Qiangning Hong <hon...@gmail.com>:

> 2008/12/25 limodou <lim...@gmail.com>:
>> 对于第三个问题,可能就与具体的框架相关了。目前不管是django也好,还是uliweb也好,其本上只有一个主wsgi应用在运行。不过因为uliweb的主要处理就是一个wsgi的app,所以是可以放在wsgi中进行使用的。
>
> Pylons是每一个Controller就是一个WSGI app。通过Routes来dispatch到某一个特定的controller运行。

我看过一些很简单的pylons的教程,它是象你说的controller方式,而uliweb是采用view的方式,互个方法只是一个简单的函数。而pylons的则首先是一个类,然后是类的方法。所以不太一样。

limodou

unread,
Dec 24, 2008, 11:25:07 PM12/24/08
to pyth...@googlegroups.com
2008/12/25 Gu Yingbo <tensi...@gmail.com>:

是的。uliweb就是使用了Debug这个wsgi进行调试。而且我还写过一个profile的wsgi middleware在uliweb中,不过平时不用。

Qiangning Hong

unread,
Dec 24, 2008, 11:49:25 PM12/24/08
to pyth...@googlegroups.com
2008/12/25 limodou <lim...@gmail.com>:

> 谢谢,这下就清楚许多了。按上面的回答,uliweb中的是Dispatcher(类名都是这么起的),所以它本身是wsgi的。在uliweb的前段时间,还可以通过config.py来添加在执行Dispatcher前的wsgi序列,不过现在去了,因为修改了许多地方,加回来也很容易。

Pylons推进Routes成为一个WSGI
middleware是一个创举,这样使得框架中的dispatcher也变成可替换的了。以前Pylons和TurboGears的最大的区别就在于一个是基于Routes一个是基于CherryPy,不可调和。现在有了WSGI
route标准,连dispatcher也可以替换了。

> 因此我想uliweb会同时支持wsgi
> middleware和django-like middleware。因为django-like
> middleware更多是在针对request, response的处理,目标比较统一。

WSGI middleware的好处是可重用性好,所有的WSGI-aware框架都可以使用。

> 对于wsgi的互用,我提第4个问题:不同的wsgi
> middleware在不同的项目中是如何互用的?是不是目前都是需要基于paster才可以?有共它的方式,还是根本不存在问题。

paste本身是一些WSGI组件的集合和工具,用不着的话当然完全可以不使用它。

paste分成三个部分,一个就叫Paste,是一个组件库,包含几个WSGI server和很多WSGI middleware。 Paste
Script提供一个命令行界面,便于创建项目、启动服务等等。Paste
Deploy提供一个配置方法,便于系统配置和部署。你如果用不到这些东西,自然不需要。

比如我自己为了在GAE上做东西玩,自己做了一个framework玩,由于只是自己用,不需要考虑配置、互换性等问题,就完全没有使用paste
script/deploy,只用了他一个middleware,代码很简单,一共142行,但基本的功能(URL
Dispatch、Template、Authentication)已经可以用了。但uliweb如果要做成一个通用的框架满足更多人的需要的话,可能还是看一下paste比较好。

#meilanweb.py

import os
import sys
import wsgiref.simple_server
import wsgiref.handlers
from types import TypeType, ClassType
import threading

import webob
import webob.exc
from routes import Mapper as _Mapper
from routes.middleware import RoutesMiddleware
from paste.exceptions.errormiddleware import ErrorMiddleware
import webhelpers as h
from mako.lookup import TemplateLookup
from google.appengine.api import users

c = threading.local()

def Mapper(*a, **kw):
prefix = kw.pop('prefix', None)
m = _Mapper(*a, **kw)
if prefix:
m.prefix = prefix
return m

def make_app(mapper, controllers, template_dir=None, debug=False):
app = Application(controllers, template_dir=template_dir)
app = AuthenticateMiddleware(app)
app = RoutesMiddleware(app, mapper)
app = ErrorDocumentMiddleware(app)
app = ErrorMiddleware(app, debug=debug)
return app

def run(app, host='', port=8080):
server = wsgiref.simple_server.make_server(host, port, app)
server.serve_forever()

def run_cgi(app):
wsgiref.handlers.CGIHandler().run(app)

class Application(object):
def __init__(self, controllers, template_dir=None):
self.controllers = controllers
if template_dir:
self.lookup = TemplateLookup(template_dir, input_encoding='utf8',
output_encoding='utf8')

def __call__(self, environ, start_response):
controller = self.resolve(environ)
environ['meilanweb.render'] = self.render
s = controller(environ, start_response)
return s

def resolve(self, environ):
"""Get the controller app from the environ."""
match = environ['wsgiorg.routing_args'][1]
try:
controller_name = match['controller']
except KeyError:
raise webob.exc.HTTPNotFound()
controller_class_name = \
class_name_from_controller_name(controller_name)
controller = self.controllers[controller_class_name]
if isinstance(controller, (TypeType, ClassType)):
controller = controller()
return controller

def render(self, template, **kwargs):
return self.lookup.get_template(template).render(**kwargs)


def class_name_from_controller_name(controller_name):
# the code is stolen from Pylons
"""
Excample::

>>> class_name_from_controller_name('with-dashes')
'WithDashes'
>>> class_name_from_controller_name('with_underscores')
'WithUnderscores'
>>> class_name_from_controller_name('oneword')
'Oneword'
"""
words = controller_name.replace('-', '_').split('_')
return ''.join(w.title() for w in words)


class Controller(object):
def __call__(self, environ, start_response):
c.__dict__.clear()
self.environ = environ
match = environ['wsgiorg.routing_args'][1]
action_name = match['action'].replace('-', '_')
action = getattr(self, action_name)
kwargs = match.copy()
del kwargs['controller']
del kwargs['action']
self.request = webob.Request(environ)
self.response = webob.Response(request=self.request)
retval = action(**kwargs)
if retval:
self.response.write(retval)
return self.response(environ, start_response)

def render(self, template, **kwargs):
return self.environ['meilanweb.render'](template, c=c, h=h, **kwargs)


def default_template_dir(filepath):
here = os.path.dirname(os.path.abspath(filepath))
return os.path.join(here, 'templates')


class ErrorDocumentMiddleware(object):
def __init__(self, app):
self.app = app

def __call__(self, environ, start_response):
try:
return self.app(environ, start_response)
except webob.exc.WSGIHTTPException, e:
e.environ = environ
return e(environ, start_response)


class AuthenticateMiddleware(object):
def __init__(self, app):
self.app = app

def __call__(self, environ, start_response):
user = users.get_current_user()
if user:
environ['REMOTE_USER'] = user
try:
return self.app(environ, start_response)
except webob.exc.HTTPUnauthorized, e:
req = webob.Request(environ)
url = users.create_login_url(req.url)
raise webob.exc.HTTPTemporaryRedirect(location=url)

h.create_logout_url = users.create_logout_url

Qiangning Hong

unread,
Dec 24, 2008, 11:57:43 PM12/24/08
to pyth...@googlegroups.com
2008/12/25 limodou <lim...@gmail.com>:

> 2008/12/25 Qiangning Hong <hon...@gmail.com>:
>> 2008/12/25 limodou <lim...@gmail.com>:
>>> 对于第三个问题,可能就与具体的框架相关了。目前不管是django也好,还是uliweb也好,其本上只有一个主wsgi应用在运行。不过因为uliweb的主要处理就是一个wsgi的app,所以是可以放在wsgi中进行使用的。
>>
>> Pylons是每一个Controller就是一个WSGI app。通过Routes来dispatch到某一个特定的controller运行。
>
> 我看过一些很简单的pylons的教程,它是象你说的controller方式,而uliweb是采用view的方式,互个方法只是一个简单的函数。而pylons的则首先是一个类,然后是类的方法。所以不太一样。

Pylons是从RoR抄过来的,所以有Controller/View的概念。喜欢用函数的话,完全也可以写成一个函数就是一个WSGI
application的。比如写成这样:

def say_hello(environ, start_response):
start_response("200 OK", [('Content-type', 'text/plain')])
return ["Hello %s!" %environ['selector.vars']['name']]

from selector import Selector

s = Selector()
s.add('/myapp/hello/{name}', GET=say_hello)

from flup.server.scgi import WSGIServer
WSGIServer(s).run()

selector是一个WSGI URL Dispatcher Middleware,根据URL选择一个WSGI app运行,主页在
http://lukearno.com/projects/selector/ 。用Routes也可以实现类似效果。

limodou

unread,
Dec 25, 2008, 12:00:07 AM12/25/08
to pyth...@googlegroups.com
2008/12/25 Qiangning Hong <hon...@gmail.com>:

> 2008/12/25 limodou <lim...@gmail.com>:
>> 谢谢,这下就清楚许多了。按上面的回答,uliweb中的是Dispatcher(类名都是这么起的),所以它本身是wsgi的。在uliweb的前段时间,还可以通过config.py来添加在执行Dispatcher前的wsgi序列,不过现在去了,因为修改了许多地方,加回来也很容易。
>
> Pylons推进Routes成为一个WSGI
> middleware是一个创举,这样使得框架中的dispatcher也变成可替换的了。以前Pylons和TurboGears的最大的区别就在于一个是基于Routes一个是基于CherryPy,不可调和。现在有了WSGI
> route标准,连dispatcher也可以替换了。
>
>> 因此我想uliweb会同时支持wsgi
>> middleware和django-like middleware。因为django-like
>> middleware更多是在针对request, response的处理,目标比较统一。
>
> WSGI middleware的好处是可重用性好,所有的WSGI-aware框架都可以使用。
>
>> 对于wsgi的互用,我提第4个问题:不同的wsgi
>> middleware在不同的项目中是如何互用的?是不是目前都是需要基于paster才可以?有共它的方式,还是根本不存在问题。
>
> paste本身是一些WSGI组件的集合和工具,用不着的话当然完全可以不使用它。
>
> paste分成三个部分,一个就叫Paste,是一个组件库,包含几个WSGI server和很多WSGI middleware。 Paste
> Script提供一个命令行界面,便于创建项目、启动服务等等。Paste
> Deploy提供一个配置方法,便于系统配置和部署。你如果用不到这些东西,自然不需要。
>
[...]

感谢。需要慢慢理解,因为方式与uliweb还有很大差距。

Qiangning Hong

unread,
Dec 25, 2008, 12:07:50 AM12/25/08
to pyth...@googlegroups.com
2008/12/25 limodou <lim...@gmail.com>:

> 是的。uliweb就是使用了Debug这个wsgi进行调试。而且我还写过一个profile的wsgi middleware在uliweb中,不过平时不用。

顺便说一句,paste.debug.profile.ProfileMiddleware就是一个用来做 profile 的 WSGI middleware

limodou

unread,
Dec 25, 2008, 12:15:06 AM12/25/08
to pyth...@googlegroups.com

现在想一想wsgi就是提供了一个标准的接口,可以在不同的组件之间进行互相调用。不过把view函数写成app还是感觉麻烦,一个hello在uliweb中只要:

@expose('/myapp/hello/<name>')
def hello(name):
return 'hello, %s!' % name

就可以了。按你的做法,say_hello其实是需要知道前面使用了selector的。这种我认为是一种假定的方式,可能会有问题。主要还是显得麻烦,对于开发者来说需要了解的东西太多。做为框架完全可以再简化。

有时追求复用与代码简化是冲突的,而我是希望用户用起来简单,在一定程度上的复用。而且与业务相关的处理复用本来难度就很大,倒不如考虑将与业务无关的东西复杂,并且减少对外部环境的假定或依赖更好一些。当然,具体还要看到底是什么东西是可以复用,应该如何被复用,也不是件容易的事。

limodou

unread,
Dec 25, 2008, 12:15:49 AM12/25/08
to pyth...@googlegroups.com
2008/12/25 Qiangning Hong <hon...@gmail.com>:

> 2008/12/25 limodou <lim...@gmail.com>:
>> 是的。uliweb就是使用了Debug这个wsgi进行调试。而且我还写过一个profile的wsgi middleware在uliweb中,不过平时不用。
>
> 顺便说一句,paste.debug.profile.ProfileMiddleware就是一个用来做 profile 的 WSGI middleware

哦。因为没研究过paste,所以不知道啊。有时间看一下。

潘俊勇

unread,
Dec 25, 2008, 12:21:04 AM12/25/08
to python-cn`CPyUG`华蟒用户组
我也参乎下。

1. filter/app之间使用environment的消息机制了交换数据的,这种基于消息,而非API的通讯方式,更加底层,可以减少依赖。

2. paste支持ini文件方式的部署配置,如:

[app:main]
use = egg:wo
filter-with = fs

[filter:fs]
paste.filter_factory = zopen.frs4wsgi.filter:filter_factory
directory = var/uploadtemp

[server:main]
use = egg:Paste#http
host = 0.0.0.0
port = 8092

可以看到,这里不仅支持wsgi组件关系的部署,还支持各个组件的参数配置

3. 关于dispatch, 在zope中叫做对象漫游traversal,bfg已经将这个转换成了一个可替换的中间件,在这里有说明和比较:

http://static.repoze.org/bfgdocs/narr/urlmapping.html

4. 关于profile的middleware,repoze社区有了repoze.profile,这里有个可用的中间件清单:

http://repoze.org/repoze_components.html#middleware

其中repoze.what作为认证的中间件,功能很强。

好像paste社区也有一个wsgi middleware清单的,刚刚没找到。

目前paste社区和repoze社区关系非常紧密的,一些中间件开发力量和项目也合并起来的。


On 12月25日, 下午12时49分, "Qiangning Hong" <hon...@gmail.com> wrote:
> 2008/12/25 limodou <limo...@gmail.com>:

Zoom.Quiet

unread,
Dec 25, 2008, 12:26:04 AM12/25/08
to pyth...@googlegroups.com, ZPyUG~珠江三角区Py用户组, pyth...@googlegroups.com
老仙都出来了哪!,,,
共142行 的又一框架也冒出来了,,,
http://wiki.woodpecker.org.cn/moin/WSGI 努力追忆中,,,

2008/12/25 潘俊勇 <panju...@gmail.com>:

--
http://zoomquiet.org
'''过程改进乃是催生可促生靠谱的人的组织!'''
Free as in Freedom! 哲思自由软件社区:http://zeuux.org

Qiangning Hong

unread,
Dec 25, 2008, 12:28:04 AM12/25/08
to pyth...@googlegroups.com
2008/12/25 limodou <lim...@gmail.com>:
> 2008/12/25 Qiangning Hong <hon...@gmail.com>:
>> Pylons是从RoR抄过来的,所以有Controller/View的概念。喜欢用函数的话,完全也可以写成一个函数就是一个WSGI
>> application的。比如写成这样:
>>
>> def say_hello(environ, start_response):
>> start_response("200 OK", [('Content-type', 'text/plain')])
>> return ["Hello %s!" %environ['selector.vars']['name']]
>>
>> from selector import Selector
>>
>> s = Selector()
>> s.add('/myapp/hello/{name}', GET=say_hello)
>>
>> from flup.server.scgi import WSGIServer
>> WSGIServer(s).run()
>>
>> selector是一个WSGI URL Dispatcher Middleware,根据URL选择一个WSGI app运行,主页在
>> http://lukearno.com/projects/selector/ 。用Routes也可以实现类似效果。
>>
>
> 现在想一想wsgi就是提供了一个标准的接口,可以在不同的组件之间进行互相调用。不过把view函数写成app还是感觉麻烦,一个hello在uliweb中只要:
>
> @expose('/myapp/hello/<name>')
> def hello(name):
> return 'hello, %s!' % name
>
> 就可以了。按你的做法,say_hello其实是需要知道前面使用了selector的。这种我认为是一种假定的方式,可能会有问题。主要还是显得麻烦,对于开发者来说需要了解的东西太多。做为框架完全可以再简化。

那个仅仅是selector的一个演示而已,一般情况下view里面是不需要使用selector.vars的。

框架要干的事情就是把问题简化,比如用selector的作者写的另一个工具yaro的话,上面的例子就变成这样:

from yaro import Yaro

@Yaro
def hello_world(req):
return "Hello World!"

from selector import Selector
s = Selector()
s.add('/myapp/hello/{name}', GET=say_hello)
from flup.server.scgi import WSGIServer
WSGIServer(s).run()

完全还可以更简单。比如我前面贴的meilanweb.py里Controller.__call__里面那一堆就是为了让写应用的时候变简单的,写代码时只要操作webob的对象就可以了,不用涉及WSGI的细节。

> 有时追求复用与代码简化是冲突的,而我是希望用户用起来简单,在一定程度上的复用。而且与业务相关的处理复用本来难度就很大,倒不如考虑将与业务无关的东西复杂,并且减少对外部环境的假定或依赖更好一些。当然,具体还要看到底是什么东西是可以复用,应该如何被复用,也不是件容易的事。


--
Qiangning Hong
http://www.douban.com/people/hongqn/

limodou

unread,
Dec 25, 2008, 12:58:22 AM12/25/08
to pyth...@googlegroups.com
2008/12/25 Qiangning Hong <hon...@gmail.com>:

到是可以考虑把uliweb下的expose改造一下,一方面进行url的注册,另一方面将一个view函数封装成一个wsgi的application的东西。

这样的话,哪些东西做成wsgi方式的会有意义呢?因为一个功能,依赖越少可能越好。而象view这样的东西,多数与你的后台,逻辑相关,这些东西比较困难。直接把框架的部分功能做成wsgi方式的有难度,因为框架最具特色的可能就是组件的搭配,配置管理,组件管理和开发方式,思想,而这些东西好象也很难wsgi化。而且有些根本与wsgi的处理无关的,象组件的管理,配置管理之类的。现在想不出来uliweb有哪些可能是独持的可以做成wsgi的东西,因为uliweb能实现的功能,别人基本上都有。而且涉及到wsgi的别人的比uliweb的好象还要更多。

黄毅

unread,
Dec 25, 2008, 1:10:47 AM12/25/08
to pyth...@googlegroups.com
2008/12/25 limodou <lim...@gmail.com>
希望对wsgi了解的介绍下:

1. WSGI的app之间如何传递消息?在environ中添加吗?
 
app 之间不传递什么信息,wsgi还是很底层的东西,并不同于MVC中的controller吧。
 


2. 多个app之间通过wsgi方式来工作,一般是怎么被调用的?它们的调用如何实现配置化?

3. 对于request, response这样的东西如何在wsgi中处理,如何传递?是每次通过environ直接生成吗?如:

request = Request(environ)

这样做,会不会有效率问题。另外如何处理request中动态添加的属性,丢失吗?
 
request 由 app 入口的地方构建一个,然后传递给业务逻辑处理的函数,不过这些都是app内部的事情了。
 


先想这么多。

--
I like python!
UliPad <<The Python Editor>>: http://code.google.com/p/ulipad/
UliWeb <<simple web framework>>: http://uliwebproject.appspot.com
My Blog: (new)http://http://hi.baidu.com/limodou
(old)http://www.donews.net/limodou




黄毅

unread,
Dec 25, 2008, 1:23:07 AM12/25/08
to pyth...@googlegroups.com
我也认为 MVC框架没必要把 controller 变成 wsgi application,一个框架应该只是一个wsgi app而已。
WSGI中间件很重要的一点是要对 app 保持透明,这样才能在不同框架间重用,有些框架内部的事情就没必要非做成wsgi middleware。

黄毅

unread,
Dec 25, 2008, 1:29:54 AM12/25/08
to pyth...@googlegroups.com

到是可以考虑把uliweb下的expose改造一下,一方面进行url的注册,另一方面将一个view函数封装成一个wsgi的application的东西。

这样的话,哪些东西做成wsgi方式的会有意义呢?因为一个功能,依赖越少可能越好。而象view这样的东西,多数与你的后台,逻辑相关,这些东西比较困难。直接把框架的部分功能做成wsgi方式的有难度,因为框架最具特色的可能就是组件的搭配,配置管理,组件管理和开发方式,思想,而这些东西好象也很难wsgi化。而且有些根本与wsgi的处理无关的,象组件的管理,配置管理之类的。现在想不出来uliweb有哪些可能是独持的可以做成wsgi的东西,因为uliweb能实现的功能,别人基本上都有。而且涉及到wsgi的别人的比uliweb的好象还要更多。
 
我想框架对wsgi友好的含义,一是把自己暴露为一个符合标准wsgi app,二是尽可能抽象出并重用对框架app透明的wsgi middleware,就够了。框架肯定会有很多自己的东西,wsgi并不是一个框架。


--
http://codeplayer.blogspot.com/

limodou

unread,
Dec 25, 2008, 1:43:49 AM12/25/08
to pyth...@googlegroups.com
2008/12/25 黄毅 <yi.cod...@gmail.com>:

那这样看来,uliweb基本上已经够了。本身是一个wsgi的app。目前也没有什么可以重用的并且对app透明的wsgi。

黄毅

unread,
Dec 25, 2008, 1:44:40 AM12/25/08
to pyth...@googlegroups.com
2008/12/25 Qiangning Hong <hon...@gmail.com>
url dispatcher 准确地说来不是标准的 wsgi middleware ,因为对 app 来说并不透明。但是因为似乎几乎所有 web framework 都带有这个东西,大家就商量了一下,往 environ 加入一个约定好的标准的key,用来存储解析url的结果,这样 url dispatcher 就可以做成是框架透明的了。

Qiangning Hong

unread,
Dec 25, 2008, 1:45:03 AM12/25/08
to pyth...@googlegroups.com
2008/12/25 limodou <lim...@gmail.com>:

> 这样的话,哪些东西做成wsgi方式的会有意义呢?因为一个功能,依赖越少可能越好。而象view这样的东西,多数与你的后台,逻辑相关,这些东西比较困难。直接把框架的部分功能做成wsgi方式的有难度,因为框架最具特色的可能就是组件的搭配,配置管理,组件管理和开发方式,思想,而这些东西好象也很难wsgi化。而且有些根本与wsgi的处理无关的,象组件的管理,配置管理之类的。现在想不出来uliweb有哪些可能是独持的可以做成wsgi的东西,因为uliweb能实现的功能,别人基本上都有。而且涉及到wsgi的别人的比uliweb的好象还要更多。

可重用的部分做成wsgi middleware的方式就是有意义的。把框架内部的各组件都做成WSGI化的,有助于从中提炼出来可重用的部分。

对于Pylons而言,这个框架的终极思想就是没有框架,只作为一个WSGI组件的粘合剂存在,每个人用的Pylons都是不一样的。所以他尽可能的把各个组件都WSGI化,用户根据自己的偏好去搭建。TurboGears
2.0挑选了自己喜欢的一些组件(比如Genshi之类),作为默认组件,就可以在Pylons上建立起一个有特点的框架。

Uliweb如果也要走"不可知"的道路,那最后也是这样的模型。所以我提议uliweb多看看pylons,如果能在pylons之上构架框架,会少走很多弯路,产生出来的结果也会更有意义(正如TurboGears项目贡献出来很多WSGI组件一样)。

Qiangning Hong

unread,
Dec 25, 2008, 1:47:06 AM12/25/08
to pyth...@googlegroups.com
2008/12/25 limodou <lim...@gmail.com>:
> 2008/12/25 黄毅 <yi.cod...@gmail.com>:

>> 我想框架对wsgi友好的含义,一是把自己暴露为一个符合标准wsgi app,二是尽可能抽象出并重用对框架app透明的wsgi
>> middleware,就够了。框架肯定会有很多自己的东西,wsgi并不是一个框架。
>
> 那这样看来,uliweb基本上已经够了。本身是一个wsgi的app。目前也没有什么可以重用的并且对app透明的wsgi。

比如我很看好的uliweb的可重用app模型,如果能够独立成一个wsgi
app,就可以直接在Pylons里重用了。这样uliweb就成为一个可重用的wsgi的app的集合,而非一个巨型的大wsgi app。

Qiangning Hong

unread,
Dec 25, 2008, 1:49:34 AM12/25/08
to pyth...@googlegroups.com
2008/12/25 黄毅 <yi.cod...@gmail.com>:

> 我也认为 MVC框架没必要把 controller 变成 wsgi application,一个框架应该只是一个wsgi app而已。
> WSGI中间件很重要的一点是要对 app 保持透明,这样才能在不同框架间重用,有些框架内部的事情就没必要非做成wsgi middleware。

Controller本身是wsgi app有一个好处,即在框架内部也可以直接使用wsgi
middlewares来进行定制。比如不同的controller使用不同的authentication机制,我就可以用不同的auth
middleware去decorate相应的controller。如果只在整个框架外部才暴露一个wsgi
app接口,那内部的这些东西都只能用私有的模式实现,重用度就大大降低了。

Qiangning Hong

unread,
Dec 25, 2008, 1:53:00 AM12/25/08
to pyth...@googlegroups.com
2008/12/25 黄毅 <yi.cod...@gmail.com>:

> url dispatcher 准确地说来不是标准的 wsgi middleware ,因为对 app 来说并不透明。但是因为似乎几乎所有 web
> framework 都带有这个东西,大家就商量了一下,往 environ 加入一个约定好的标准的key,用来存储解析url的结果,这样 url
> dispatcher 就可以做成是框架透明的了。

所以我说Pylons社区推进routing标准化是一个创举。

可以想象,如果request对象也标准化了,比如都使用和webob相同的接口,那各个框架之间的鸿沟又可以再大大缩小一步,wsgi组件在不同框架间可重用的程度也可以大大增加。

limodou

unread,
Dec 25, 2008, 1:57:19 AM12/25/08
to pyth...@googlegroups.com
2008/12/25 Qiangning Hong <hon...@gmail.com>:

uliweb的不可知只是核心部分,它可以被其他人用来构建定制化的东西。所以一般用户使用的应该是可知的。并且我希望uliweb在工作时,会有一个缺省选择,用户可以更换,但不配置时就是缺省的。不过要完全做到不可知很难,因为你的调用接口总要的统一的,但这些可能只是一个局部的标准,别人不一定能遵守或做到,所以要么采用和别人一样的接口,但是仍然可能有不满足的情况。要么自已来定义接口,由用户来针对不同的组件进行适配。

其实没有框架就意味着按照自已的方式来组织框架,就是我说的定制化。只不过只有wsgi还无法完成web的处理,我们还需要象template,
orm之类的通用模块,而这些与wsgi没什么关系也是一个问题。所以全部wsgi首先是不可能,完全利用wsgi搭建的也只是处理这一块,还有许多的工作要处理。因此我想定制化不一定要在wsgi之上,可以是在一个初步定制化的基础之上的二次定制。

黄毅

unread,
Dec 25, 2008, 1:58:15 AM12/25/08
to pyth...@googlegroups.com
2008/12/25 Qiangning Hong <hon...@gmail.com>

2008/12/25 黄毅 <yi.cod...@gmail.com>:
> 我也认为 MVC框架没必要把 controller 变成 wsgi application,一个框架应该只是一个wsgi app而已。
> WSGI中间件很重要的一点是要对 app 保持透明,这样才能在不同框架间重用,有些框架内部的事情就没必要非做成wsgi middleware。

Controller本身是wsgi app有一个好处,即在框架内部也可以直接使用wsgi
middlewares来进行定制。比如不同的controller使用不同的authentication机制,我就可以用不同的auth
middleware去decorate相应的controller。如果只在整个框架外部才暴露一个wsgi
app接口,那内部的这些东西都只能用私有的模式实现,重用度就大大降低了。
 
这样就有一个问题,authentication 组件做成 wsgi middleware 的话需要自己去解析请求,但作为一个 app 内部的组件的话,可以由app对请求解析一次,authentication 直接取解析后的数据即可。
除非说要把 request、response对象也标准化,那按照这条路走下去的话,就是要搞一个标准统一所有框架,变成一个大一统的框架而已。

limodou

unread,
Dec 25, 2008, 2:02:02 AM12/25/08
to pyth...@googlegroups.com
2008/12/25 Qiangning Hong <hon...@gmail.com>:

> 2008/12/25 limodou <lim...@gmail.com>:
>> 2008/12/25 黄毅 <yi.cod...@gmail.com>:
>>> 我想框架对wsgi友好的含义,一是把自己暴露为一个符合标准wsgi app,二是尽可能抽象出并重用对框架app透明的wsgi
>>> middleware,就够了。框架肯定会有很多自己的东西,wsgi并不是一个框架。
>>
>> 那这样看来,uliweb基本上已经够了。本身是一个wsgi的app。目前也没有什么可以重用的并且对app透明的wsgi。
>
> 比如我很看好的uliweb的可重用app模型,如果能够独立成一个wsgi
> app,就可以直接在Pylons里重用了。这样uliweb就成为一个可重用的wsgi的app的集合,而非一个巨型的大wsgi app。
>

这个想法到是很有意思。不过uliweb的app其实就是一个python的包,它包含了静态信息,配置信息,翻译信息等。uliweb在启动时可以根据配置或动态发现它们,然后合并它们的配置信息,提取url等,而这些处理都是由Dispatcher来完成的。所以这些app并不是一个wsgi的应用。不太明白你希望的重用是什么样子,是Dispatcher还是那些个app?

Qiangning Hong

unread,
Dec 25, 2008, 2:06:24 AM12/25/08
to pyth...@googlegroups.com
2008/12/25 limodou <lim...@gmail.com>:

> uliweb的不可知只是核心部分,它可以被其他人用来构建定制化的东西。所以一般用户使用的应该是可知的。并且我希望uliweb在工作时,会有一个缺省选择,用户可以更换,但不配置时就是缺省的。不过要完全做到不可知很难,因为你的调用接口总要的统一的,但这些可能只是一个局部的标准,别人不一定能遵守或做到,所以要么采用和别人一样的接口,但是仍然可能有不满足的情况。要么自已来定义接口,由用户来针对不同的组件进行适配。

这个就是TurboGears的路线。TurboGears原来就是完全自己做,选择自己喜欢的第三方组件搭建框架,和RoR一样。等发展到一定程度了,用的人多了,就开始有替换组件的需求。弄来弄去,最后发现直接在Pylons上搭建,选择一套默认组件,由Pylons去负责组件的可替换性,TurboGears只需要专注在用户的易用性和功能增强上面就行了,这样的方案对整个社区都有利。所以才有了TurboGears
2.0。

> 其实没有框架就意味着按照自已的方式来组织框架,就是我说的定制化。只不过只有wsgi还无法完成web的处理,我们还需要象template,
> orm之类的通用模块,而这些与wsgi没什么关系也是一个问题。所以全部wsgi首先是不可能,完全利用wsgi搭建的也只是处理这一块,还有许多的工作要处理。因此我想定制化不一定要在wsgi之上,可以是在一个初步定制化的基础之上的二次定制。

template的WSGI化: http://pypi.python.org/pypi/wsgiview/
ORM的WSGI化: http://pypi.python.org/pypi/Alchemyware

limodou

unread,
Dec 25, 2008, 2:07:47 AM12/25/08
to pyth...@googlegroups.com
2008/12/25 黄毅 <yi.cod...@gmail.com>:

的确是这样,对于django的auth
middleware我很理解,并且它在处理后会将用户对象赋组request上。而authkit是一个wsgi
middleware,它如何关心后台的用户机制是数据库,还是ldap,还是什么的,又如何与request相关联的呢?因为用户认证的情况在后面的应用处理也要使用的。不知道它怎么做的?

Qiangning Hong

unread,
Dec 25, 2008, 2:10:49 AM12/25/08
to pyth...@googlegroups.com
2008/12/25 黄毅 <yi.cod...@gmail.com>:

> 这样就有一个问题,authentication 组件做成 wsgi middleware 的话需要自己去解析请求,但作为一个 app
> 内部的组件的话,可以由app对请求解析一次,authentication 直接取解析后的数据即可。
> 除非说要把 request、response对象也标准化,那按照这条路走下去的话,就是要搞一个标准统一所有框架,变成一个大一统的框架而已。

如果不希望在authentication组件里面自己解析request的话,可以在authentication
middleware前面套一个解析request的middleware,比如webob。这样这个authentication
middleware只依赖于这个request parser middleware,而不是依赖于整个框架。所有其他使用那个request
parser middleware,也就是webob的wsgi框架都可以使用这些authentication
middleware,可重用性显然要好很多。

BTW,我是希望看到request对象标准化的,webob很有这方面的潜质。

Qiangning Hong

unread,
Dec 25, 2008, 2:17:04 AM12/25/08
to pyth...@googlegroups.com
2008/12/25 limodou <lim...@gmail.com>:

> 这个想法到是很有意思。不过uliweb的app其实就是一个python的包,它包含了静态信息,配置信息,翻译信息等。uliweb在启动时可以根据配置或动态发现它们,然后合并它们的配置信息,提取url等,而这些处理都是由Dispatcher来完成的。所以这些app并不是一个wsgi的应用。不太明白你希望的重用是什么样子,是Dispatcher还是那些个app?

如果uliweb能变成一个wsgi middleware,把它往其他的wsgi
app上一套,那些app就能像在uliweb里一样变得可重用了,这个世界就很美妙了 :)

不过我对uliweb理解不深,不知道能不能实现。

Zoom.Quiet

unread,
Dec 25, 2008, 2:18:23 AM12/25/08
to pyth...@googlegroups.com, pyth...@googlegroups.com, ec...@googlegroups.com
2008/12/25 Qiangning Hong <hon...@gmail.com>:

> 如果不希望在authentication组件里面自己解析request的话,可以在authentication
> middleware前面套一个解析request的middleware,比如webob。这样这个authentication
> middleware只依赖于这个request parser middleware,而不是依赖于整个框架。所有其他使用那个request
> parser middleware,也就是webob的wsgi框架都可以使用这些authentication
> middleware,可重用性显然要好很多。
>
> BTW,我是希望看到request对象标准化的,webob很有这方面的潜质。


哗!越发的精彩了,都是实用哲学思考哪,,只是大家手中的论据和基础都不同,,,
http://wiki.woodpecker.org.cn/moin/WSGI/AskWSGI?action=show#head-255817bea60f1ec2f50957ce933bbab49b4d0f82

及时转发相关社区体会,,
,

--
http://zoomquiet.org
'''过程改进乃是催生可促生靠谱的人的组织!'''
一个人如果力求完善自己,就会看到:为此也必须同时完善他人. 一个人如果不关心别人的完善,自己便不可能完善!

limodou

unread,
Dec 25, 2008, 2:22:05 AM12/25/08
to pyth...@googlegroups.com
2008/12/25 Qiangning Hong <hon...@gmail.com>:

> 2008/12/25 limodou <lim...@gmail.com>:
>> uliweb的不可知只是核心部分,它可以被其他人用来构建定制化的东西。所以一般用户使用的应该是可知的。并且我希望uliweb在工作时,会有一个缺省选择,用户可以更换,但不配置时就是缺省的。不过要完全做到不可知很难,因为你的调用接口总要的统一的,但这些可能只是一个局部的标准,别人不一定能遵守或做到,所以要么采用和别人一样的接口,但是仍然可能有不满足的情况。要么自已来定义接口,由用户来针对不同的组件进行适配。
>
> 这个就是TurboGears的路线。TurboGears原来就是完全自己做,选择自己喜欢的第三方组件搭建框架,和RoR一样。等发展到一定程度了,用的人多了,就开始有替换组件的需求。弄来弄去,最后发现直接在Pylons上搭建,选择一套默认组件,由Pylons去负责组件的可替换性,TurboGears只需要专注在用户的易用性和功能增强上面就行了,这样的方案对整个社区都有利。所以才有了TurboGears
> 2.0。
>

就象是最新我看到的merb与ror的关系很象。不过pylons毕竟还是一个相对独立的框架,它也有自已的选择。

>> 其实没有框架就意味着按照自已的方式来组织框架,就是我说的定制化。只不过只有wsgi还无法完成web的处理,我们还需要象template,
>> orm之类的通用模块,而这些与wsgi没什么关系也是一个问题。所以全部wsgi首先是不可能,完全利用wsgi搭建的也只是处理这一块,还有许多的工作要处理。因此我想定制化不一定要在wsgi之上,可以是在一个初步定制化的基础之上的二次定制。
>
> template的WSGI化: http://pypi.python.org/pypi/wsgiview/

这个是把模板的处理进行了包装,可以返回一个wsgi的application。虽然是一种办法,但是我并不认为到处都是wsgi就可以简化web开发,还不如自动对应模板来得简单。应该把这种处理封装到框架内部,如果让一般的web用户来使用,太麻烦,我感觉不好。

> ORM的WSGI化: http://pypi.python.org/pypi/Alchemyware
>

好象会共享出一个session对象,起到了一个全局化的作用。这也算ORM的wsgi?好象与使用全局模块不是一样吗?

Qiangning Hong

unread,
Dec 25, 2008, 2:22:34 AM12/25/08
to pyth...@googlegroups.com
2008/12/25 limodou <lim...@gmail.com>:

> 的确是这样,对于django的auth
> middleware我很理解,并且它在处理后会将用户对象赋组request上。而authkit是一个wsgi
> middleware,它如何关心后台的用户机制是数据库,还是ldap,还是什么的,又如何与request相关联的呢?因为用户认证的情况在后面的应用处理也要使用的。不知道它怎么做的?

AuthKit有一大堆的初始化参数,来选择认证模式、数据后端等等。处理request是用的webob。处理后得到的数据是放在environ里供后面的app使用的。

BTW, AuthKit很不好用,我比较看好这个 http://trac.sandbox.lt/auth/wiki/WhyWsgiMiddleware

limodou

unread,
Dec 25, 2008, 2:24:10 AM12/25/08
to pyth...@googlegroups.com
2008/12/25 Qiangning Hong <hon...@gmail.com>:

> 2008/12/25 limodou <lim...@gmail.com>:
>> 这个想法到是很有意思。不过uliweb的app其实就是一个python的包,它包含了静态信息,配置信息,翻译信息等。uliweb在启动时可以根据配置或动态发现它们,然后合并它们的配置信息,提取url等,而这些处理都是由Dispatcher来完成的。所以这些app并不是一个wsgi的应用。不太明白你希望的重用是什么样子,是Dispatcher还是那些个app?
>
> 如果uliweb能变成一个wsgi middleware,把它往其他的wsgi
> app上一套,那些app就能像在uliweb里一样变得可重用了,这个世界就很美妙了 :)
>

uliweb的app是一个包,不是一个真正的对象啊,怎么套啊。不是一样的东西。

> 不过我对uliweb理解不深,不知道能不能实现。

黄毅

unread,
Dec 25, 2008, 2:24:53 AM12/25/08
to pyth...@googlegroups.com
2008/12/25 Qiangning Hong <hon...@gmail.com>
我觉得上面这两个路子不对,还是认为不是什么东西都可以通过扩展wsgi来做,template已经turbogears已经有一个叫做 buffet 的标准化接口了吧,我觉得那个已经够了。

limodou

unread,
Dec 25, 2008, 2:30:26 AM12/25/08
to pyth...@googlegroups.com
2008/12/25 Qiangning Hong <hon...@gmail.com>:

> 2008/12/25 limodou <lim...@gmail.com>:
>> 的确是这样,对于django的auth
>> middleware我很理解,并且它在处理后会将用户对象赋组request上。而authkit是一个wsgi
>> middleware,它如何关心后台的用户机制是数据库,还是ldap,还是什么的,又如何与request相关联的呢?因为用户认证的情况在后面的应用处理也要使用的。不知道它怎么做的?
>
> AuthKit有一大堆的初始化参数,来选择认证模式、数据后端等等。处理request是用的webob。处理后得到的数据是放在environ里供后面的app使用的。
>
> BTW, AuthKit很不好用,我比较看好这个 http://trac.sandbox.lt/auth/wiki/WhyWsgiMiddleware
>

这个好象挺有意思,有时间我研究研究。

Qiangning Hong

unread,
Dec 25, 2008, 2:34:20 AM12/25/08
to pyth...@googlegroups.com
2008/12/25 limodou <lim...@gmail.com>:

>> template的WSGI化: http://pypi.python.org/pypi/wsgiview/
>
> 这个是把模板的处理进行了包装,可以返回一个wsgi的application。虽然是一种办法,但是我并不认为到处都是wsgi就可以简化web开发,还不如自动对应模板来得简单。应该把这种处理封装到框架内部,如果让一般的web用户来使用,太麻烦,我感觉不好。

我也觉得这个没什么大用,因为基本上到模板的时候,app把应该干的事情都已经干完了,渲染模板仅仅是一个函数调用,所以看不出来把渲染这件事情做成wsgi
app有什么实质的好处。贴出来只是说一下有人在做这样的事情。

>> ORM的WSGI化: http://pypi.python.org/pypi/Alchemyware
>
> 好象会共享出一个session对象,起到了一个全局化的作用。这也算ORM的wsgi?好象与使用全局模块不是一样吗?

这个的作用很大,可以打破不同的middleware对SQLAlchemy全局变量调用可能存在的冲突。如果一个middleware对SQLAlchemy的使用有特殊性,可以放在自己的session里,不和其他的发生冲突。

Qiangning Hong

unread,
Dec 25, 2008, 2:35:13 AM12/25/08
to pyth...@googlegroups.com
2008/12/25 limodou <lim...@gmail.com>:
> uliweb的app是一个包,不是一个真正的对象啊,怎么套啊。不是一样的东西。

给这个包加上 __call__(start_response, environ) 试试?

Zoom.Quiet

unread,
Dec 25, 2008, 2:37:36 AM12/25/08
to pyth...@googlegroups.com
2008/12/25 Qiangning Hong <hon...@gmail.com>:
> 给这个包加上 __call__(start_response, environ) 试试?

每个简洁的接口背后,都对应一个腌臜的实现,,,,


--
http://zoomquiet.org
'''过程改进乃是催生可促生靠谱的人的组织!'''
金山常年招聘Py/C++人才! http://bit.ly/UoTV 简历直投俺就成;-)

limodou

unread,
Dec 25, 2008, 2:45:40 AM12/25/08
to pyth...@googlegroups.com
2008/12/25 Qiangning Hong <hon...@gmail.com>:

> 2008/12/25 limodou <lim...@gmail.com>:
>> uliweb的app是一个包,不是一个真正的对象啊,怎么套啊。不是一样的东西。
>
> 给这个包加上 __call__(start_response, environ) 试试?
>

不行啊。app在uliweb是一个组织或开发单位,不是一个运行单位。一个app下面可能有views.py,它里面才是真正的处理函数,但是可能有很多。

limodou

unread,
Dec 25, 2008, 2:46:34 AM12/25/08
to pyth...@googlegroups.com
2008/12/25 limodou <lim...@gmail.com>:

> 2008/12/25 Qiangning Hong <hon...@gmail.com>:
>> 2008/12/25 limodou <lim...@gmail.com>:
>>> uliweb的app是一个包,不是一个真正的对象啊,怎么套啊。不是一样的东西。
>>
>> 给这个包加上 __call__(start_response, environ) 试试?
>>
>
> 不行啊。app在uliweb是一个组织或开发单位,不是一个运行单位。一个app下面可能有views.py,它里面才是真正的处理函数,但是可能有很多。
>

而且一个app可以只有一些公共的文件,静态的文件,如一些配置信息,js文件什么的,可能连views.py都没有。

潘俊勇

unread,
Dec 25, 2008, 8:11:37 PM12/25/08
to python-cn`CPyUG`华蟒用户组

On 12月25日, 下午3时02分, limodou <limo...@gmail.com> wrote:
> 2008/12/25 Qiangning Hong <hon...@gmail.com>:
>

> > 2008/12/25 limodou <limo...@gmail.com>:
> >> 2008/12/25 黄毅 <yi.codepla...@gmail.com>:


> >>> 我想框架对wsgi友好的含义,一是把自己暴露为一个符合标准wsgi app,二是尽可能抽象出并重用对框架app透明的wsgi
> >>> middleware,就够了。框架肯定会有很多自己的东西,wsgi并不是一个框架。
>
> >> 那这样看来,uliweb基本上已经够了。本身是一个wsgi的app。目前也没有什么可以重用的并且对app透明的wsgi。
>
> > 比如我很看好的uliweb的可重用app模型,如果能够独立成一个wsgi
> > app,就可以直接在Pylons里重用了。这样uliweb就成为一个可重用的wsgi的app的集合,而非一个巨型的大wsgi app。
>
> 这个想法到是很有意思。不过uliweb的app其实就是一个python的包,它包含了静态信息,配置信息,翻译信息等。uliweb在启动时可以根据配置或动态发现它们,然后合并它们的配置信息,提取url等,而这些处理都是由Dispatcher来完成的。所以这些app并不是一个wsgi的应用。不太明白你希望的重用是什么样子,是Dispatcher还是那些个app?
>

其实repoze社区已经有authentication的中间件了啊(repoze.who, repoze.what),paste也已经把
request/response标准化了。
而且repoze社区和paste社区就是在做这个事情。

Bruce Wang

unread,
Dec 25, 2008, 9:21:12 PM12/25/08
to pyth...@googlegroups.com


2008/12/26 潘俊勇 <panju...@gmail.com>



其实repoze社区已经有authentication的中间件了啊(repoze.who, repoze.what),paste也已经把
request/response标准化了。
而且repoze社区和paste社区就是在做这个事情。


repoze的 wsgi middleware 是完全独立的,还是依赖zope3 的呢?
(zope社区的东西最害怕有一堆dependency)


--
simple is good
http://brucewang.net
http://twitter.com/number5

Gu Yingbo

unread,
Dec 25, 2008, 9:25:40 PM12/25/08
to pyth...@googlegroups.com


2008/12/26 Bruce Wang <num...@gmail.com>



2008/12/26 潘俊勇 <panju...@gmail.com>



其实repoze社区已经有authentication的中间件了啊(repoze.who, repoze.what),paste也已经把
request/response标准化了。
而且repoze社区和paste社区就是在做这个事情。


repoze的 wsgi middleware 是完全独立的,还是依赖zope3 的呢?
(zope社区的东西最害怕有一堆dependency)

说得太对了,好像zope里的东西依赖都很强,从zope里摘点东西出来太困难了。

黄毅

unread,
Dec 26, 2008, 3:06:33 AM12/26/08
to pyth...@googlegroups.com
再啰嗦几句,web框架要统一就要标准化组件之间的接口,但这些已经不是wsgi关注的领域了。
environ字典对 app 来说只代表最原始的 web请求,它不应该是框架内部组件之间交换数据的场所。
框架应该在入口处统一解析一次 environ,并构造一个 request 对象,其后的事情都应该建立在这个request对象的基础之上,而不用再去直接处理environ了,
url dispatcher解析URL的结果也应该存放在这个 request 对象中,而不是 environ 中。
像 url dispatcher、auth 这些都应该是框架内的组件,比如说可以有一个框架内的middleware协议,就像 django 的middleware那样,不需要wsgi那么复杂,它们之间就只需要传递 request和response 对象即可,environ、start_response对它们来说都是太底层的东西。
而 wsgi middleware 一定要对所有wsgi application透明,这是我理解的 wsgi。
标准化web框架应该是在 web框架内部做的事情,而不应该一味地去扩展wsgi,试图把 wsgi 变成一个框架。
标准化web框架也不准确,顶多是标准化一个MVC的web框架。
uliweb没怎么看过,不过我认为limudou完全不必把controller变成wsgi application,应该把框架暴露成一个wsgi app,并且制定一些框架内部组件之间的标准化接口,比如框架内的middleware之间的接口,存取配置的接口,调用模板的接口,使用ORM的接口等。

limodou

unread,
Dec 26, 2008, 3:24:10 AM12/26/08
to pyth...@googlegroups.com
2008/12/26 黄毅 <yi.cod...@gmail.com>:


好的建议。一个框架中有许多的处理,有些是与wsgi相关的,有些不是。所以只有wsgi统一化也只解决了一部分问题。从看到的一些wsgi
middleware的互访来说,它们其实也约定了许多标准的组件,比如sqlalchemy,
webob等。而这些只是组件的选择上的一致性,还没有达到接口的规范统一。不过这是很难的,而且也不知道是否真有意义。

现在uliweb基本上就是你说的样子。middleware的标准基本上和django是一样的,不过我增加了一个__init__的定义,这样是可以进行初始化的,做一些特殊的事情。

v cc

unread,
Dec 26, 2008, 4:16:56 AM12/26/08
to pyth...@googlegroups.com
2008/12/26 limodou <lim...@gmail.com>

2008/12/26 黄毅 <yi.cod...@gmail.com>:
> 再啰嗦几句,web框架要统一就要标准化组件之间的接口,但这些已经不是wsgi关注的领域了。
> environ字典对 app 来说只代表最原始的 web请求,它不应该是框架内部组件之间交换数据的场所。
> 框架应该在入口处统一解析一次 environ,并构造一个 request
> 对象,其后的事情都应该建立在这个request对象的基础之上,而不用再去直接处理environ了,
> url dispatcher解析URL的结果也应该存放在这个 request 对象中,而不是 environ 中。
> 像 url dispatcher、auth 这些都应该是框架内的组件,比如说可以有一个框架内的middleware协议,就像 django
> 的middleware那样,不需要wsgi那么复杂,它们之间就只需要传递
> request和response 对象即可,environ、start_response对它们来说都是太底层的东西。
> 而 wsgi middleware 一定要对所有wsgi application透明,这是我理解的 wsgi。
> 标准化web框架应该是在 web框架内部做的事情,而不应该一味地去扩展wsgi,试图把 wsgi 变成一个框架。
> 标准化web框架也不准确,顶多是标准化一个MVC的web框架。
> uliweb没怎么看过,不过我认为limudou完全不必把controller变成wsgi application,应该把框架暴露成一个wsgi
> app,并且制定一些框架内部组件之间的标准化接口,比如框架内的middleware之间的接口,存取配置的接口,调用模板的接口,使用ORM的接口等。


好的建议。一个框架中有许多的处理,有些是与wsgi相关的,有些不是。所以只有wsgi统一化也只解决了一部分问题。从看到的一些wsgi
middleware的互访来说,它们其实也约定了许多标准的组件,比如sqlalchemy,
webob等。而这些只是组件的选择上的一致性,还没有达到接口的规范统一。不过这是很难的,而且也不知道是否真有意义。

现在uliweb基本上就是你说的样子。middleware的标准基本上和django是一样的,不过我增加了一个__init__的定义,这样是可以进行初始化的,做一些特殊的事情。
 
确实,完全没必要什么都做成middleware,要知道middleware可是每次请求都挨个挨个调用的啊,几百个middleware一起调用是什么样的场景,那性能简直....想象一下,几百的middleware一起排队,一边调用一边打招呼:Hi,你今天WSGI了没? ;-)
 
黄毅说得很对,WSGI是个很底层的协议,应该做他底层的事,不要来做app重用这么高级的事啊。
 
vcc
_

潘俊勇

unread,
Dec 26, 2008, 10:19:17 AM12/26/08
to python-cn`CPyUG`华蟒用户组
既然做成中间件,就是要解决依赖的。没有多余的依赖的。

On 12月26日, 上午10时21分, "Bruce Wang" <numb...@gmail.com> wrote:
> 2008/12/26 潘俊勇 <panjuny...@gmail.com>

张沈鹏

unread,
Dec 26, 2008, 11:04:42 PM12/26/08
to pyth...@googlegroups.com
pylons 的weberror是个好东西
可以单独用
很方便就叫上了 错误调试 还是ajax互交的

limodou

unread,
Dec 26, 2008, 11:41:13 PM12/26/08
to pyth...@googlegroups.com
2008/12/27 张沈鹏 <zsp...@gmail.com>:

> pylons 的weberror是个好东西
> 可以单独用
> 很方便就叫上了 错误调试 还是ajax互交的
>

werkzeug带一个DebugApplication不知道是不是一个东西。uliweb中就使用了。

张沈鹏

unread,
Dec 27, 2008, 3:20:20 AM12/27/08
to pyth...@googlegroups.com
发一张截图
就加了这么一句话
from weberror.evalexception import EvalException
app = EvalException(Application())
zzs.jpg

limodou

unread,
Dec 27, 2008, 3:24:17 AM12/27/08
to pyth...@googlegroups.com
2008/12/27 张沈鹏 <zsp...@gmail.com>:

有些象,附werkzeug的截图:

Image00006.jpg

Zoom.Quiet

unread,
Dec 27, 2008, 7:35:10 AM12/27/08
to pyth...@googlegroups.com
2008/12/27 张沈鹏 <zsp...@gmail.com>:

可以输入的命令是可以现场探查一些值?!
super cool!

--
http://zoomquiet.org
'''过程改进乃是催生可促生靠谱的人的组织!'''
PE keeps evolving organizations which promoting people be good!

limodou

unread,
Dec 27, 2008, 7:44:14 AM12/27/08
to pyth...@googlegroups.com
2008/12/27 Zoom. Quiet <zoom....@gmail.com>:

> 2008/12/27 张沈鹏 <zsp...@gmail.com>:
>> 发一张截图
>> 就加了这么一句话
>> from weberror.evalexception import EvalException
>> app = EvalException(Application())
>>
>
> 可以输入的命令是可以现场探查一些值?!
> super cool!
>

是的。

Zoom.Quiet

unread,
Dec 27, 2008, 7:54:00 AM12/27/08
to pyth...@googlegroups.com
2008/12/27 limodou <lim...@gmail.com>:

> 2008/12/27 Zoom. Quiet <zoom....@gmail.com>:
>> 2008/12/27 张沈鹏 <zsp...@gmail.com>:
>>> 发一张截图
>>> 就加了这么一句话
>>> from weberror.evalexception import EvalException
>>> app = EvalException(Application())
>>>
>>
>> 可以输入的命令是可以现场探查一些值?!
>> super cool!
>>
>
> 是的。
>

soooooo sweat tools ! collection into:
MiscItems/2008-12-27 - Woodpecker.org.cn Wiki for CPUG
http://wiki.woodpecker.org.cn/moin/MiscItems/2008-12-27


--
http://zoomquiet.org
'''过程改进乃是催生可促生靠谱的人的组织!'''
usage 7-zip to replace WinRAR/WinZip; You can get the truely Freedom 4 software.

Reply all
Reply to author
Forward
0 new messages