A Session ClassΒΆ

Since session state maintenance happens in many pages a session class is in order.

Save the next program as session.py and import it in all pages in which session state is required. The session object will try to create a directory named session in the document root if it doesn’t exist. If it can’t you will have to create it yourself and chmod it to 2770

import sha, shelve, time, Cookie, os

class Session(object):

    def __init__(self, expires=None, cookie_path=None):
        string_cookie = os.environ.get('HTTP_COOKIE', '')
        self.cookie = Cookie.SimpleCookie()
        self.cookie.load(string_cookie)

        if self.cookie.get('sid'):
            sid = self.cookie['sid'].value
            # Clear session cookie from other cookies
            self.cookie.clear()

        else:
            self.cookie.clear()
            sid = sha.new(repr(time.time())).hexdigest()

        self.cookie['sid'] = sid

        if cookie_path:
            self.cookie['sid']['path'] = cookie_path

        session_dir = os.environ['DOCUMENT_ROOT'] + '/session'
        if not os.path.exists(session_dir):
            try:
                os.mkdir(session_dir, 02770)
                # If the apache user can't create it do it manualy
            except OSError, e:
                errmsg =  """
                    %s when trying to create the session directory.
                    Create it as '%s'
                """ % (e.strerror, os.path.abspath(session_dir))
                raise OSError, errmsg

        self.data = shelve.open (
            '%s/sess_%s' % (session_dir, sid), 
            writeback=True
        )
        os.chmod('%s/sess_%s' % (session_dir, sid), 0660)

        # Initializes the expires data
        if not self.data.get('cookie'):
            self.data['cookie'] = {'expires':''}

        self.set_expires(expires)

    def close(self):
        self.data.close()

    def set_expires(self, expires=None):
        if expires == '':
            self.data['cookie']['expires'] = ''
        elif isinstance(expires, int):
            self.data['cookie']['expires'] = expires

        self.cookie['sid']['expires'] = self.data['cookie']['expires']

An example of the session class usage:

#!/usr/bin/env python
import cgitb; cgitb.enable()

# Some hosts will need to have document_root appended
# to sys.path to be able to find user modules
import sys, os
sys.path.append(os.environ['DOCUMENT_ROOT'])

import session, time

sess = session.Session(expires=365*24*60*60, cookie_path='/')
# expires can be reset at any moment:
sess.set_expires('')
# or changed:
sess.set_expires(30*24*60*60)

# Session data is a dictionary like object
lastvisit = sess.data.get('lastvisit')
if lastvisit:
    message = 'Welcome back. Your last visit was at ' + \
        time.asctime(time.gmtime(float(lastvisit)))
else:
    message = 'New session'

# Save the current time in the session
sess.data['lastvisit'] = repr(time.time())
print """\
%s
Content-Type: text/plain\n
sess.cookie = %s
sess.data = %s
%s
""" % (sess.cookie, sess.cookie, sess.data, message)
sess.close()