Alice
Alice

Reputation: 485

GAE: How can a handler return a webapp2.Response when using sessions and overriding `dispatch`?

I adapted this sample code in order to get webapp2 sessions to work on Google App Engine.

What do I need to do to be able to return webapp2.Response objects from a handler that's inheriting from a BaseHandler that overrides the dispatch method?

Here's a demonstration of the kind of handler I want to write:

import webapp2
import logging

from webapp2_extras import sessions


class BaseHandler(webapp2.RequestHandler):
  def dispatch(self):
    # Get a session store for this request.
    self.session_store = sessions.get_store(request=self.request)
    try:
      # Dispatch the request.
      webapp2.RequestHandler.dispatch(self)
    finally:
      # Save all sessions.
      self.session_store.save_sessions(self.response)


class HomeHandler(BaseHandler):
  def get(self):
    logging.debug('In homehandler')
    response = webapp2.Response()
    response.write('Foo')
    return response

config = {}
config['webapp2_extras.sessions'] = {
    'secret_key': 'some-secret-key',
}


app = webapp2.WSGIApplication([
    ('/test', HomeHandler),
], debug=True, config=config)


This code is obviously not working, since BaseHandler always calls dispatch with self. I've looked through the code of webapp2.RequestHandler, but it seriously eludes me how to modify my BaseHandler (or perhaps set a custom dispatcher) such that I can simply return response objects from inheriting handlers.

Curiously, the shortcut of assigning self.response = copy.deepcopy(response) does not work either.

Upvotes: 1

Views: 1441

Answers (2)

Sarah Happy
Sarah Happy

Reputation: 283

I took a look at webapp2.RequestHandler and noticed that returned values are just passed up the stack.

A solution which works for me is to use the returned Response when one is returned from the handler, or self.response when nothing is returned.

class BaseHandler(webapp2.RequestHandler):
    def dispatch(self):
        # Get a session store for this request.
        self.session_store = sessions.get_store(request=self.request)

        response = None
        try:
            # Dispatch the request.
            response = webapp2.RequestHandler.dispatch(self)
            return response
        finally:
            # Save all sessions.
            if response is None:
                response = self.response
            self.session_store.save_sessions(response)

While I was playing I noticed that my session stored as a secure cookie was not getting updated when exceptions were raised in the handler.

Upvotes: 0

Brent Washburne
Brent Washburne

Reputation: 13138

You're mixing the two responses in one method. Use either

return webapp2.Response('Foo')

or

self.response.write('Foo')

...not both.

Upvotes: 0

Related Questions