spyce
home
license
community
download
examples
resources
wishlist
contrib (@sf)
documentation
intro
lang
runtime
modules
tags
install
exits
sourceforge
statistics
freshmeat

Documentation - Modules
[[ Spyce ]]
Python Server Pages
by Rimon Barr

Prev: 4.10 - Cookie Up: 4 - Modules Next: 4.12 - Pool

4.11. Session

Sessions allow information to be efficiently passed from one request to the next via some browser mechanism: get, post or cookie. The potentially large or sensitive information is stored at the server, and only a short identifier is sent to the client. Sessions are often used to create sequences of pages that represent an application flow. This module manages session state. All session state has an expiration time and is automatically garbage collected.

  • setHandler( type, [ params ] ):
    Selects the session handler. This method must be called before invoking other session functions. The type specifies the handler, and the param(s) is (are) passed to the initialiser of the chosen handler. The type parameter is a string of the format: "file:class", where file is the location where the session handler is defined and class is the name of the session handler. The file name component is optional, and is searched for using the standard module-finding rules. If only the class name is specified, then the default location is used: inside the session module itself, where the standard Spyce session handlers reside.

    The standard Spyce session handlers are listed below, along with the parameters they take. If you would like to implement your own, custom session handler, there are two ways to do so. First, you can have a look at modules/session.py and define your subclass of the sessionHandler class. One would do this when defining a general-purpose session handler, and if you do go to this trouble, please email it in as a contribution. Alternatively, you can simply use the session_user handler, also defined below, to your own install callback functions. The majority of users should be satisfied with the basic session handlers provided.

    • setHandler( 'session_dir', directory ):
      Uses inidividual files in the specified directory to store session information.
    • setHandler( 'session_gdbm', file ):
      Uses the gdbm library to create and manage the session information inside the specified file.
    • setHandler( 'session_bsddb', file ):
      Uses the BSD database library to create and manage the session information inside the specified file.
    • setHandler( 'session_user', getf, setf, delf, idsf, info ):
      Uses user-provided functions to create and manage session information. The parameters are as follows:
      • getf: A function that will be called to get session state, as follows: getf(info, id), where info is the parameter given to setHandler above, and id is the session identifier. This function should ensure that the session has not expired. If an expired session is found, it must be automatically deleted. Note that a delete may never be called on an object, so it is imperative for getf() to delete objects when expiration is detected. If the session has expired, or if the session does not exist, this function should return None, otherwise the session information.
      • setf: A function that will be called to set or create session state, as follows: setf(info, state, expire, serverID, id), where info is the parameter given to setHandler above, state is the actual session information to be preserved, expire is the number of seconds after which this information will be invalidated, serverID is a unique identifier for this server that can be used to avoid race conditions between two Spyce engines generating new session identifiers, and id is the optional session identifier. If an identifier is provided, that session should be updated, otherwise (namely, in the case when id is set to None), a new session identifier should be generated. This function returns the (new or old) session identifier.
      • delf: A function that will be called to set delete a session, as follows: delf(info, id), where info is the parameter given to the setHandler above and id is the session identifier of the session to be invalidated.
      • idsf: A function that will be called to get all the session identifiers, as follows: idsf(info), where info is the parameter given to the setHandler above. This function should return ALL session identifiers, even those that have expired and are to be deleted. Among other purposes, this function is used to automatically clean up session state periodically, by performing a getf() on all sessions. (Remember that according to the semantics defined for getf(), it will delete any expired sessions.)
      • info: At the very least, this is a key that uniquely identifies this session handler. The info variable may also contain any other additional information. It is passed back as-is to each of the session callback functions, as described previously.

  • get( id ):
    Returns the object stored under the given id. If the id does not exist, or was previously used but has expired, then None is returned. As with the cookie module, the session module may be treated as an associative array when retrieving session information.
  • set( data, expire, [id] ):
    Stores the data object under the given id. If id is omitted, then a unique one is generated. On success, an id is returned, otherwise an exception raised. The expire field specifies the number of seconds that the session information is valid for.
  • delete( id ):
    Deletes the session stored under the given id. Note that sessions are automatically deleted upon expiration, so this method need only be used when immediate invalidation is desired. As with the cookie module, the session module may be treated as an associative array when removing session information.
  • autoSession( expire, [method], [name] ):
    This function can remove most of the code associated with session management, by doing it automatically. Namely, it automatically retrieves the session information and resaves it at the end of the request, using the auto, autoID, autoName and autoMethod fields (explained below). The expire parameters acts as before, to specify how long the session information remains valid. The method and name parameters instruct the session module how to find the session identifier. Method can be one of 'get', 'post', or 'cookie', which is the default. The name parameter, under which the session id is stored, defaults to 'spyceSession'. If the lookup is unable to find a session id for this request a new session is created. At the end of the request, the session information is automatically saved, and a cookie automatically generated if the 'cookie' method was chosen. For the 'get' and 'post' methods the user is required to encode the autoID (session id) inside all form targets and urls that are generated.
  • auto:
    The field containing the actual session information, when automatic session management is used. Set it to whatever you like, as long as it can be serialized. Its initial value, for a new session, is None.
  • autoID:
    The session identifier, when automatiic session management is used.
  • autoName:
    The variable named used to identify the cookie or the parameter in the get or post requests containing the session identifier, when automatic session management is used.
  • autoMethod:
    The method used ('cookie', 'post' or 'get') to load and save the session identifier, when automatic session management is used.
The example below shows how a session can be used to count the number of times the same open browser visited our page. The session ID is stored in a cookie that expires when the browser is closed. Note that the session module automatically loads the cookie module if not already loaded and is needed.

examples/session.spy
[[.import name=cookie]]
[[.import name=session args="'session_dir', '/tmp'"]]
<html><body>
  [[-- retrieve session information --]]
  [[\
    sessionid = cookie.get('session')
    if sessionid:
      num = session.get(sessionid)
      if num==None:
        sessionid = None
        num = 0
      else: num = int(num)
    else: num = 0
  ]]
  [[-- output --]]
  Your session ID was: [[=sessionid]]<br>
  [[num = num + 1]]
  You have visited this page [[=num]] time(s).<br>
  [[-- save session information for next time --]]
  [[\
    sessionid = session.set( num, 10, sessionid )
    if sessionid: cookie.set('session', sessionid)
  ]]
  Your session ID is now: [[=sessionid]]<br>
  Session expiration = 10 seconds.<br>
  <b>Note:</b> This example requires write access to 
  the /tmp directory to function correctly.
</body></html>
Run this code.
(requires Spyce-enabled web server)

The next example highlights the convenience of using autoSession. By default, the session identifier is stored using a cookie named 'spyceSession'.

examples/autosession.spy
[[.import name=session args="'session_dir', '/tmp', auto=10"]]
<html><body>
  [[-- count visits --]]
  [[\ 
    if not session.auto: session.auto = 1
    else: session.auto = session.auto + 1
  ]]
  [[-- output --]]
  You have visited this page [[=session.auto]] time(s)<br>
  Your autosession ID is: [[=session.autoID]]<br>
  Autosession expiration = 10 seconds.<br>
  <b>Note:</b> This example requires write access to 
  the /tmp directory to function correctly.
</body></html>
Run this code.
(requires Spyce-enabled web server)

If cookies are not desired, the automatic session identifier session.autoID can also be transmitted via a browser post, as shown:

examples/autosessionpost.spy
[[.import name=session args="'session_dir','/tmp', auto=(10,'post','mysession')"]]
<html><body>
  [[-- count visits --]]
  [[\
    if not session.auto: session.auto = 1
    else: session.auto = session.auto + 1
  ]]
  [[-- output --]]
  You have visited this page [[=session.auto]] time(s)<br>
  Your autosession ID is: [[=session.autoID]]<br>
  Autosession expiration = 10 seconds.<br>
  <table><tr>
    <td>
      <form method=post>
        <input type=submit value=Refresh>
        <input type=hidden name=mysession value=[[=session.autoID]]>
      </form>
      </td><td>
      <form method=post>
        <input type=submit value=Clear>
      </form>
    </td>
  </tr></table><br>
  <b>Note:</b> This example requires write access to 
  the /tmp directory to function correctly.
</body></html>
Run this code.
(requires Spyce-enabled web server)

Finally, one can easily define some new session handling mechanism using callback functions, as this last example shows:

examples/mysession.spy
[[.import names="pool,session"]]
[[-- note: this eg will not work under CGI
     or when you have multiple servers --]]
[[\
  # storing session info as server pool variable,
  # so that example is portable! -- you'll 
  # want to have some persistent DB connection.
  if not pool.has_key('mysession'):
    pool['mysession'] = {}
    pool['mysessioncount'] = 1
  def myget(info, id):
    import time
    try:
      state, expiretime = pool['mysession'][id]
      if int(time.time()) > expiretime:
        del pool['mysession'][id]
        return None
      return state
    except KeyError:
      return None
  def myset(info, state, expire, serverID, id):
    import time
    if not id:
      # lock here if running threaded engine
      id = str(pool['mysessioncount'])
      pool['mysessioncount'] = pool['mysessioncount'] + 1
    pool['mysession'][id] = state, int(time.time())+expire
    return id
  def mydel(info, id):
    try: del pool['mysession'][id]
    except KeyError: pass
  def myids(info):
    return pool['mysession'].keys()
  session.setHandler('session_user', myget, myset, mydel, myids, 'mysession')
  session.autoSession(10)
]]
<html><body>
  [[-- count visits --]]
  [[\ 
    if not session.auto: session.auto = 1
    else: session.auto = session.auto + 1
  ]]
  [[-- output --]]
  You have visited this page [[=session.auto]] time(s)<br>
  Your autosession ID is: [[=session.autoID]]<br>
  Autosession expiration = 10 seconds.<br>
  <b>Note:</b> This example requires a persistent server (i.e. non-CGI)
  to function correctly.
</body></html>
Run this code.
(requires Spyce-enabled web server)


Prev: 4.10 - Cookie Up: 4 - Modules Next: 4.12 - Pool


© 2002-06 Rimon Barr
email: rimon@acm.org
Spyce Powered SourceForge Logo [[ Spyce ]]
Python Server Pages
version 1.3.13