Sessioning provides a persistant storage for arbitrary data between user requests. Typically the user is sent a cookie containing a randomly generated identification string in the response to the first request to the WSGI application. This session cookie is used to identify the browser session and Pesto makes a data store available in the variable request.session that is persistent between requests in the same session.
A middleware layer must be added to the application that deals with setting and checking the session cookie.
As an alternative to using cookies the session identfier may also be passed around in the querystring portion of the URL, however this requires special care when writing the application to include the session identifier in every URL generated by your application.
Here’s an example application using sessions:
from pesto import DispatcherApp
app = DispatcherApp()
@app.match('/login', 'POST')
def login(request):
username = request.get('username')
password = request.get('password')
if is_valid(username, password):
request.session['username'] = username
request.session['logged_in'] = True
@app.match('/secure-area', 'GET')
def secure_area(request):
if not request.session.get('logged_in'):
return response.redirect(login.url())
return ["Welcome to the secure area, %s" % request.session['username']]
from pesto.session.filesessionmanager import FileSessionManager
# Create a file based sessioning middleware, that runs a purge every 600s
# for sessions older than 1800s..
sessioning = pesto.session_middleware(
FileSessionManager('/path/to/session/store'),
auto_purge_every=600,
auto_purge_olderthan=1800
)
app = sessioning(app)
Sessioning needs some kind of data storage backend. The two backends available in Pesto are memory and file backed storage.
Synopsis:
from pesto.session.filesessionmanager import FileSessionManager
app = pesto.session_middleware(FileSessionManager('/path/to/session/store'))(app)
This backend is the most generally useful storage backend. Session data is stored in one file per session, using Python’s pickle module to store and retrieve data from disk. The application must have access to a writable directory, which for security reasons should not be readable by other users.
Synopsis:
from pesto.session.memorysessionmanager import MemorySessionManager
app = pesto.session_middleware(MemorySessionManager())(app)
This implementation stores data directly in a python data structure stored in memory. Session data can’t be shared between processes and is lost when the process finishes, so it is not useful for CGI or architectures that do not use long-running processes or architectures that split requests between multiple processes. In general it is recommended to use the file backend which does not suffer from these problems.
There are two built in methods for associating a session with a user request, using either HTTP cookies or the URI querystring.
This is the default method and is usually preferred as it is transparent both to users and the application developer. However not all browsers accept cookies and cookies cannot easily be passed between applications running on different domains, for these reasons you may still prefer the querystring based approach.
Cookie based persistence is the default method so no extra code is required to enable this:
app = pesto.session_middleware(FileSessionManager('/path/to/session/store'))(app)
When using cookie based persistence cookies are by default tied to the path and domain on which the application is running. To override this, you can specify the cookie path and domain when constructing the session middleware:
app = pesto.session_middleware(
FileSessionManager('/path/to/session/store'),
cookie_path='/',
cookie_domain='.example.org',
)(app)
If you are using the filesessionmanager this could be used to share session state between WSGI applications running on the same server mounted on different subdomains or paths.
To set up a pesto application with querystring based persistence:
app = pesto.session_middleware(
FileSessionManager('/path/to/session/store'),
persist='querystring'
)(app)
When querystrings are used it is necessary for all links generated by the application to contain a reference to the session id. Thus code to generate a link would typically look like this (this example uses the Genshi page template syntax):
<a href="/some-page?pesto_session=${request.session.session_id}">...</a>
Pesto doesn’t contain any code to support rewriting links output by your application, it is up to you to ensure the querystring is always present in links.
Any GET requests that do not contain a session id will be redirected by the session middleware to a URL containing a fresh session identifier if one is not already present.
Web session management.
WSGI middleware application for sessioning.
Synopsis:
>>> from pesto.session.memorysessionmanager import MemorySessionManager
>>> def my_wsgi_app(environ, start_response):
... session = environ['pesto.session']
...
>>> app = session_middleware(MemorySessionManager())(my_wsgi_app)
>>>
Either cookie or querystring. If set to cookie then sessions will be automatically persisted via a session cookie.
If querystring then the session-id will be read from the querystring. However it is up to the underlying application to ensure that the session-id is embedded into all links generated by the application.
Store request sessions in memory
Usage:
>>> from pesto.session import session_middleware
>>> from pesto.session.memorysessionmanager import MemorySessionManager
>>> def my_app(environ, start_response):
... start_response('200 OK', [('Content-Type', 'text/html')])
... yield "<html>Whoa nelly!</html>"
...
>>> manager = MemorySessionManager()
>>> app = session_middleware(manager)(my_app)
An in-memory session manager.
Synopsis:
>>> from pesto.session import session_middleware
>>> from pesto.session.memorysessionmanager import MemorySessionManager
>>> manager = MemorySessionManager()
>>> def app(environ, start_response):
... "WSGI application code here"
...
>>> app = session_middleware(manager)(app)
>>>
Store request sessions in flat files.
Usage:
>>> from pesto.session import session_middleware
>>> from pesto.session.filesessionmanager import FileSessionManager
>>> def my_app(environ, start_response):
... start_response('200 OK', [('Content-Type', 'text/html')])
... yield "<html>Whoa nelly!</html>"
...
>>> manager = FileSessionManager('./sessions')
>>> app = session_middleware(manager)(my_app)
A File-backed session manager.
Synopsis:
>>> from pesto.session import session_middleware
>>> from pesto.session.filesessionmanager import FileSessionManager
>>> manager = FileSessionManager('/tmp/sessions')
>>> def app(environ, start_response):
... "WSGI application code here"
...
>>> app = session_middleware(manager)(app)
>>>
Acquire lock for the storage
Return the time the given session was last accessed. Note that this uses the underlying filesystem’s atime attribute, so will not work on filesystems mounted with noatime
Return the path to the file where session data is stored.
Synopsis:
>>> from pesto.session.base import Session
>>> fsm = FileSessionManager(directory='/tmp')
>>> session = Session(fsm, 'abcdefgh', True)
>>> fsm.get_path(session.session_id)
'/tmp/_pesto_sessions/ab/abcdefgh'
Release lock for the storage
Store session to a file
Update session access time, by calling os.utime on the session file.