随手记录一下查看nova代码时的笔记。nova.wsgi文件定义了wsgi功能组件的基类。
nova.wsgi.Application模块的解析
此类为wsgi app的基类:
class Application(object):
"""WSGI应用程序基类封装. 子类需要实现__call__方法."""
@classmethod
def factory(cls, global_config, **local_config):
"""在paste.deploy配置文件中被调用
任何local配置 (即paste配置文件中[app:APPNAME]的值) 都将作为kwargs传递到 `__init__` 方法中。
假设的配置内容如下: [app:wadl]
latest_version = 1.3
paste.app_factory = nova.api.fancy_api:Wadl.factory
这样就可以实现paste类似如下的方式调用Wadl类: import nova.api.fancy_api
fancy_api.Wadl(latest_version='1.3')
当然,您可以在子类中重新实现`factory`方法,但是使用kwarg传递它应该是不必要的。
"""
return cls(**local_config)
def __call__(self, environ, start_response):
""" 子类可以类似下面的内容去实现__call__:
@webob.dec.wsgify(RequestClass=Request)
def __call__(self, req):
# 以下任何对象都可以作为responses:
# Option 1: 简单字符串
res = 'message\n'
# Option 2: 格式化良好的HTTP异常页面
res = exc.HTTPForbidden(explanation='Nice try')
# Option 3: 一个webob Response object (需要处理header等内容...)
res = Response()
res.app_iter = open('somefile')
# Option 4: 接下来运行的任何wsgi应用程序
res = self.application
# Option 5: 可以为wsgi应用程序获取一个Response对象,以处理header等内容
res = req.get_response(self.application)
# 也可以只返回response...
return res
# ... 或设置req.response然后返回None.
req.response = res
See the end of http://pythonpaste.org/webob/modules/dec.html
for more info.
"""
raise NotImplementedError(_('You must implement __call__'))
nova.wsgi.Router模块的解析
此类为nova路由器系统的基类:
class Router(object):
"""此类是WSGI中间件,可以将传入请求映射到WSGI应用程序."""
def __init__(self, mapper):
""" 为给定的routes.Mapper创建一个路由器.
`mapper`中的每个路由必须指定一个'controller'。指定一个'action'并让控制器成为一个对象,
这样可以将请求路由到特定于action的方法。
Examples:
mapper = routes.Mapper()
sc = ServerController()
# 一个路由到controller+action的显式映射
mapper.connect(None, '/svrlist', controller=sc, action='list')
# Actions都是隐式定义的
mapper.resource('server', 'servers', controller=sc)
# 指向任意的WSGI app. 可以指定{path_info:.*}参数,
# 这样目标应用程序就可以只传递URL的这一部分。
mapper.connect(None, '/v1.0/{path_info:.*}', controller=BlogApp())
"""
self.map = mapper
self._router = routes.middleware.RoutesMiddleware(self._dispatch, self.map)
@webob.dec.wsgify(RequestClass=Request)
def __call__(self, req):
""" 将传入请求路由到基于self.map的控制器。 如果不匹配,返回404。
"""
return self._router
@staticmethod
@webob.dec.wsgify(RequestClass=Request)
def _dispatch(req):
""" 将请求分派到适当的控制器。 将传入请求与路由匹配并将信息放入 req.environ 由self._router调用。
"""
match = req.environ['wsgiorg.routing_args'][1]
if not match:
return webob.exc.HTTPNotFound()
app = match['controller']
return app
nova.wsgi.Middleware模块的解析
class Middleware(Application):
""" WSGI中间件基类.
#这些类需要初始化一个应用程序,该应用程序将在下一步调用。
#默认情况下,中间件只调用其封装的应用程序,或者可以重载__call__ 方法来自定处理行为。
"""
@classmethod
def factory(cls, global_config, **local_config):
"""在paste.deploy配置文件中被调用
任何local配置 (即paste配置文件中[app:APPNAME]的值) 都将作为kwargs传递到 `__init__` 方法中。
假设的配置内容如下:
[filter:analytics]
redis_host = 127.0.0.1
paste.filter_factory = nova.api.analytics:Analytics.factory
可以实现如python调用 `Analytics` 类方式行为,如下所示:
import nova.api.analytics
analytics.Analytics(app_from_paste, redis_host='127.0.0.1')
当然,您可以在子类中重新实现`factory`方法
"""
def _factory(app):
return cls(app, **local_config)
return _factory
def __init__(self, application):
self.application = application
def process_request(self, req):
"""在每个request中调用.
#如果它不返回任何值,则继续执行堆栈中的下一个应用程序。
#如果它返回一个响应,那么该响应将被返回,执行将在这里停止。
"""
return None
def process_response(self, response):
"""返回response前可以进行一些预处理."""
return response
@webob.dec.wsgify(RequestClass=Request)
def __call__(self, req):
response = self.process_request(req)#调用此方法处理api请求
if response:
return response #如果有响应则返回,一般情况有response代表着有异常
response = req.get_response(self.application)#执行wsgi 应用程序获取响应
return self.process_response(response)#调用此方法预处理响应。