[albatross-users] Session management how-to?

Andrew McNamara andrewm at object-craft.com.au
Wed Jun 19 11:11:48 EST 2002


>However, I need a clue or two about how to manage sessions in a
>session based application.  I'm using SimpleSessionFileApp and
>SessionFileAppContext.  Since I'm using a page object application,
>I've created a .py file with one class for each page.  So, I have
>these questions:
>
>1. How and where do I create a new session.  Do I need to? I'm
>    guessing I should put that code in the class for the start
>    page.  What code and where?  In the page_enter method?  In the
>    page_process method?

If the request from the browser contains information about an existing
session, that session is used, otherwise a new one is created.

So, in the case of the session file classes, SessionFileContextMixin
looks for a cookie containing the session id in the browser request,
and retrieves the appropriate session from the filesystem (or the
session server, in the case of the session server classes). In the case
of the hidden field classes, the session is a pickled and signed hidden
form field.

Your cgi script might contain something like this (note that I haven't
tested this - it may contain typos, but should give you the idea):

class App(albatross.SimpleSessionFileApp):
    def __init__(self):
        albatross.SimpleSessionFileApp.__init__(self,
                base_url = 'app.py',
                template_path = 'templates',
                start_page = 'login',
                secret = '*secret*',
                session_appid = 'app',
                session_dir = '/tmp/app')

    def create_context(self):
        ctx = albatross.SessionFileAppContext(self)
        # Load some macro templates here, if you like
        # ctx.run_template_once('macrostuff.html')
        return ctx

if __name__ == '__main__':
    app = App()
    app.run(Request())

>2. How and where do I delete (remove?) a session.  I'm guessing I
>    should put that code in the class for the last page of the
>    application.  What code and where?  In the page_display method
>    (and after ctx.run_template())?

If your application contains a "logout" button, you could do it in the
page_process function like this:

    if ctx.req_equals('logout'):
        ctx.remove_session()
        ctx.set_page('login')

If you have a page from which the application can go no further, you
could remove the session on entering the page (the user will never leave
the page - but reloading the page will take them back to the begining).

Note that you will need something to clean up abandoned sessions (the
client closes their browser window without signing off, etc) - the
simplest is a cron job (if you are using unix) or script that is run once
a day that deletes any files older than a day from the session directory.
This isn't necessary with other types of session application (the session
server discards old sessions itself, and the hidden field sessions are
saved by the client).

>3. And what does each page class need to do in order to ensure that
>    it is using the correct session data/state for the current
>    request?

I'm not sure what you mean here? It should be the correct session data,
because a session is unique to a user (although they can do silly things
like creating another window or hitting the back key).

>I need to understand the order and conditions under which page
>object methods page_process, page_enter, page_leave, and
>page_display are called.  Trace methods in my app and reading
>section "4.1 Albatross Application Model" of the manual have me
>less than enlightened.  Is there any place I can look for more
>explanation on the processing model that Albatross follows?

For a page class called "blah", blah.page_enter() is called once after the
previous page class calls ctx.set_page('blah'), and blah.page_display() is
then called (and called each time the page is redisplayed - on reload, for
example). 

When the user submits some data, blah.page_process() is called.
page_process() can act on the data, save it, or request the application to
move to a new page (ctx.set_page()). 

If the application remains on the "blah" page, blah.page_display() is
called. If set_page() was called, blah.page_leave() is called, and process
starts again with the new page class.

Note that you don't need to provide all four methods - if not provided,
they default to sensible actions in each case.

In page_enter(), you would put one time initialisation (setting default
values for form fields for example).

    def page_enter(ctx):
        ctx.locals.diagnostic = ''
        ctx.locals.whatever = load_whatever()
        ctx.add_session_vars('whatever')

In page_display(), you might initialise more form fields (ones derived from
external data, maybe), for example:

    def page_display(ctx):
        ctx.locals.load_setting_name = ctx.locals.settings.get_current_name()
        return ctx.run_template('change_parameters.html')

In page_process(), you act on the user's form submission:

    def page_process(ctx):
        if ctx.req_equals('submit'):
            if ctx.locals.username == '':
                ctx.locals.diagnostic = 'You must enter a username'
        else:
            ctx.locals.diagnostic = ''

In page_leave(), you might perform cleanup:

    def page_leave(ctx):
        ctx.remove_session_vars('whatever')


Does that help?

-- 
Andrew McNamara, Senior Developer, Object Craft
http://www.object-craft.com.au/



More information about the Albatross-users mailing list