[mod_python] session redux

Jim Gallacher jpg at jgassociates.ca
Wed May 24 22:39:15 EDT 2006


David Bear wrote:
> I'm trying to understand sessioning better. Here is a scenario:
> 
> I have a publisher script called py.py. publisher is set as the
> handler for directory.
> 
> Using py.py as a dispatcher for url named modules we have
> 
> functions in py.py 		psp pages served by function
> index 				main.psp
> register 			register.psp
> regpage2 			regp2.psp
> final				final.psp
> 
> A session object is instantiated in py.py. I assume I can pass the
> session object via the vars name to the psp template correct?
> 
> using http://myserver/py.py the index function serves main.psp.
> 
> using http://myserver/py.py/register the register.psp code is
> 'rendered'/'evaluated' and sent to the client.
> 
> Now, the question: As the user proceeds from main.psp to register.psp
> to regp2.psp and so on, how to modpython know not to create a new
> session object for each visit? Put another way, how would the
> regp2.psp page 'know' of the session object created when the user
> first visited the main.psp page?

It's magic and it all happens when you create a session instance. When 
the instance is created it checks for the existence of a cookie named 
pysid. If it finds it, it will check the persistent store (depending on 
what session class you are using) for the corresponding data and load it 
if it exists. Otherwise it will generate a new session id. Finally, the 
pysid cookie (either the existing on or the new one) will be set in the 
response headers.

The only trick is to make sure you save your session data. Otherwise 
every request will create a new session.

The only *other* trick is to make sure you only create one session 
instance per request, otherwise you'll get a deadlock. Session locking 
happens automatically and protects the integrity of your session, but 
deadlocks are a bad thing, and should be avoided. ;)

The "standard" way to pass the session instance around is as a request 
attribute. There is some further magic in psp where it looks for any 
variables named "session". If found it will use req.session if it 
exists, or create a new session using Session.Session().

Typical usage
-------------

def index(req):
    req.session = Session.Session(req)
    if req.session.is_new():
        req.session['count'] = 0
    else:
        req.session['count'] = req.session['count'] + 1

    tmpl = psp.PSP(req, filename='whatever.tmpl')
    tmpl.run()
    # Make sure you save your session!
    req.session.save()


def register(req):
    req.session = Session.Session(req)
    if req.session.is_new():
        req.session['count'] = 0
    else:
        req.session['count'] = req.session['count'] + 1
    helper_function(req)
    tmpl = psp.PSP(req, filename='whatever.tmpl')
    tmpl.run()
    # Make sure you save your session!
    req.session.save()

def helper_function(req):
    # Don't create a session instance here, use the one created in
    # in the register function.
    req.session['message'] = "You have been helped"

As you suggest you could pass the session instance to the psp template 
using vars, but if you do make sure you *do not* use "session" as a 
variable name in the template. Otherwise the magic in psp will turn out 
to be all bad and you'll deadlock.

Jim



More information about the Mod_python mailing list