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 create 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(session_dir + '/sess_' + sid, writeback=True)
      os.chmod(session_dir + '/sess_' + 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()