0

I'm trying to get sessions to work with Webapp2 with GAE, but I'm stuck retrieving the stored parameters. Maybe I'm overlooking the obvious.

A dressed down version of with main.py where I store a value in the webapp2 session:

import webapp2
from webapp2_extras import sessions
other imports...

class BaseHandler(webapp2.RequestHandler):  # Copied from Google's doc
    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)

    @webapp2.cached_property
    def session(self):
        # Returns a session using the default cookie key.
        return self.session_store.get_session()

class MainPage(webapp2.RequestHandler):  # My main page proper
    def get(self):
        self.session['foo'] = 'bar'      # Store somehing in the session
        template_values = {

        }

        template = JINJA_ENVIRONMENT.get_template('index.html')
        self.response.write(template.render(template_values))


application = webapp2.WSGIApplication([
    ('/', MainPage, ),], debug = True)

My problem is how to access the value stored in the session from another module. In test.py I do the following:

from webapp2_extras import sessions
import main
other imports ...


class Test(main.BaseHandler):
    def post(self):
        foo1 = self.session.get('foo')
        return foo1

class ProductsPage(webapp2.RequestHandler):
    def get(self):
        foo2 = Test.post()
        ...

But I get the following error: TypeError: unbound method post() must be called with Test instance as first argument (got nothing instead)

I just can't find the proper way to use the Test class and retrieve the value stored in the session. I must be overlooking something when using the class, but I'm stuck and can't find the way out.

Maybe somebody looking from outside will spot it easily?

kxtronic
  • 331
  • 5
  • 16
  • Did you properly set up sessions per e.g http://stackoverflow.com/questions/14078054/gae-webapp2-session-the-correct-process-of-creating-and-checking-sessions ? Anyway, you most assuredly can't call unbound method `Test.post` w/o having an instance of `Test` as the first arg -- that's Python 101 and totally independent of App Engine, webapp2, or sessions. (where that `Login` comes from is a mystery). Why do you need `Test` anyway -- why not roll up the inheritance and functionality right into `ProductsPage`?! – Alex Martelli Jan 18 '15 at 04:45
  • Hi Alex, indeed I had setup according to your link. And I wrongly copied the wrong error message. It's now corrected: Test instead of Login. And I see what you mean, I need an instance of Basehandler in products.py. It works in main, but I'm banging my head on how the create one within products.py. Any ideas? – kxtronic Jan 18 '15 at 22:53
  • I think you should have `ProductsPage` itself subclass `main.BaseHandler`, so it will have its own `self.session` to use. I'm perplexed that your `MainPage` works without subclassing `BaseHandler`, by the way! – Alex Martelli Jan 18 '15 at 23:43
  • Hi Alex, found the solution. I posted it below. You suggestions gave me the clue how to look further. Thanks! – kxtronic Jan 19 '15 at 22:18

1 Answers1

0

Looking further I found a post that helped me GAE webapp2 session handling not working when putting basehandler to a different file

After some tinkering here's the recipe that worked for me to setup a session in webapp2 and share the session among different .py files. Hope it saves others some time.

1) Create basehandler.py, this will need to be imported by all .py files using the session. This is straight from Google's documentation:

import webapp2
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:
            webapp2.RequestHandler.dispatch(self)
        finally:
            self.session_store.save_sessions(self.response)

    @webapp2.cached_property
    def session(self):
        # Returns a session using the default cookie key
        return self.session_store.get_session()

2) Create main.py importing BaseHandler. In my case I store a value in the session:

import os
import urllib
import webapp2
import jinja2
from basehandler import BaseHandler


JINJA_ENVIRONMENT = jinja2.Environment(
    loader=jinja2.FileSystemLoader(os.path.dirname(__file__)),
    extensions=['jinja2.ext.autoescape'])

class MainPage(BaseHandler):
    def get(self):

    self.session['foo'] = 'bar'    # Store a value in the session
                                   # you can store more than one :-)


    # Define values that will be passed onto the template 
    template_values = {
        'title': 'TITLE'
    }

    # search for an appropriate template and render it. 
    template =      JINJA_ENVIRONMENT.get_template('./templates/index.html')
    self.response.write(template.render(template_values))

config = {}
config['webapp2_extras.sessions'] = {   
'secret_key': 'my-super-secret-key'
}

application = webapp2.WSGIApplication([
    ('/', MainPage)
], config = config, debug = True)

3) Create another.py taking care to also import BaseHandler and use the same secret key. Here you can retrieve the value stored by main.py or any other .py file sharing the same session:

import os
import urllib
import webapp2
import jinja2
from basehandler import BaseHandler


JINJA_ENVIRONMENT = jinja2.Environment(
    loader=jinja2.FileSystemLoader(os.path.dirname(__file__)),
    extensions=['jinja2.ext.autoescape'])

class AnotherPage(BaseHandler):
    def get(self):

    foo1 = self.session.get('foo')

    # Now go and do something with foo1, even store a new value as in main.py
    # ...
    # ...

    # Define values that will be passed onto the template 
    template_values = {
        'title': 'TITLE'
    }

    # search for an appropriate template and render it. 
    template =      JINJA_ENVIRONMENT.get_template('./templates/additional.html')
    self.response.write(template.render(template_values))

config = {}
config['webapp2_extras.sessions'] = {   
'secret_key': 'my-super-secret-key'
}

application = webapp2.WSGIApplication([
    ('/', AdditionalPage)
], config = config, debug = True)
Community
  • 1
  • 1
kxtronic
  • 331
  • 5
  • 16