My App Engine application has a custom user model. This model is accessed frequently in the application code. I would like to simplify the code by injecting a model instance into each authenticated request before the request is handled (similar to the process_request
method of Django middleware classes).
I am using the App Engine Python2.7 standard runtime with webapp2 as the framework.
I tried creating a WSGI middleware callable that modified the WSGI environ dictionary and defined a webapp_add_wsgi_middleware
function appengine_config.py
to add the middleware, but the middleware did not run until after the request had been processed by the app.
How can I modify the request before it's handled by the application?
The solution I found was to create a subclass of webapp2.WSGIApplication
and have that modify the environ
dictionary before calling the superclass to run the app. To set the instance as an attribute of the request, rather than having to access it via Request.environ, I added it to the environ
's 'webob.adhoc_attrs' value. This is because webapp2's Request class inherits from webob's, which in turn inherits from a mixin class that manages attribute access.
Here's an example application that sets an attribute on all requests:
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)