在处理请求之前设置请求的属性

Set an attribute on a request before it's handled

我的 App Engine 应用程序有一个自定义用户模型。在应用程序代码中经常访问此模型。我想通过在处理请求之前将模型实例注入每个经过身份验证的请求来简化代码(类似于 Django 中间件 类 的 process_request 方法)。

我正在使用 App Engine Python2.7 标准 运行时间,以 webapp2 作为框架。

我尝试创建一个可调用的 WSGI 中间件,它修改了 WSGI 环境字典并定义了一个 webapp_add_wsgi_middleware 函数 appengine_config.py 来添加中间件,但是中间件 运行 直到应用已处理请求。

如何在应用程序处理请求之前修改请求?

我找到的解决方案是创建一个 webapp2.WSGIApplication 的子 class 并在调用 superclass 到 [=22= 之前修改 environ 字典] 应用程序。为了将实例设置为请求的属性,而不是必须通过 Request.environ 访问它,我将它添加到 environ 的 'webob.adhoc_attrs' 值中。这是因为 webapp2 的请求 class 继承自 webob 的,后者又继承自管理属性访问的 mixin class

这是一个在所有请求上设置属性的示例应用程序:

import webapp2


class Handler(webapp2.RequestHandler):

    def get(self):
        try:
            foo = self.request.foo
        except AttributeError:
            foo = 'Default'
        self.response.write('Hello %s' % foo)


routes = [('/', Handler)]


class MyWSGIApplication(webapp2.WSGIApplication):

    def __call__(self, environ, start_response):
        adhoc_attrs = {'foo': 'Foo'}
        if 'webob.adhoc_attrs' in environ:
            environ['webob.adhoc_attrs'].update(adhoc_attrs)
        else:
            environ['webob.adhoc_attrs'] = adhoc_attrs
        return super(MyWSGIApplication, self).__call__(environ, start_response)


app = MyWSGIApplication(routes)