Beaker (Session & Caching)
Beaker is a Python library providing robust caching and session management functionality, including WSGI middleware for web applications and decorators for standalone scripts. It supports various back-ends like file, memory, Memcached, Redis, MongoDB, and SQLAlchemy. The library is actively maintained, with the current stable version being 1.13.0.
Common errors
-
<type 'exceptions.KeyError'> at / 'beaker.session'
cause The `SessionMiddleware` was not correctly applied to the WSGI application, or the application code is attempting to access `environ['beaker.session']` before it has been made available by the middleware.fixEnsure your WSGI application is wrapped by `SessionMiddleware` with proper configuration, e.g., `application = SessionMiddleware(your_app, session_opts)`. -
TypeError: can't pickle <_io.TextIOWrapper object at ...>
cause You are attempting to store an object in the session that cannot be serialized by Python's `pickle` module, which is Beaker's default serializer.fixRefactor your code to store only primitive types or objects that are known to be pickleable. Alternatively, configure Beaker to use a different serializer: `session_opts = {..., 'session.data_serializer': 'json'}` (if your data is JSON-compatible). -
SyntaxError: invalid syntax (on a line containing 'async')
cause You are running an older version of Beaker (<1.9.1) on Python 3.7 or newer, where 'async' became a reserved keyword, causing a syntax error in Beaker's internal code.fixUpgrade the Beaker library to version 1.9.1 or later (`pip install --upgrade beaker`) to resolve the keyword conflict.
Warnings
- gotcha When using file-based or DBM backends, ensure the `session.data_dir` and `session.lock_dir` (or `cache.data_dir`, `cache.lock_dir`) directories are writable by the application. In production, these should be persistent and properly managed.
- deprecated Storing arbitrary Python objects in sessions using the default `pickle` serializer can lead to security vulnerabilities and issues with unpickleable objects. It is recommended to switch to `json` serialization if your session data permits.
- gotcha The `memory` backend for sessions is process-local. Session data will be lost if the application process restarts. This backend is generally suitable for development only.
- breaking In `beaker` versions prior to 1.9.1, `async` was used as a variable name in some internal code, which became a keyword in Python 3.7. This can lead to `SyntaxError` when running on Python 3.7 or newer.
Install
-
pip install beaker
Imports
- SessionMiddleware
from beaker import SessionMiddleware
from beaker.middleware import SessionMiddleware
- CacheManager
from beaker import CacheManager
from beaker.cache import CacheManager
Quickstart
import os
from wsgiref.simple_server import make_server
from beaker.middleware import SessionMiddleware
def simple_app(environ, start_response):
session = environ['beaker.session']
if 'counter' in session:
session['counter'] += 1
else:
session['counter'] = 1
response_body = [
f'The current counter is: {session["counter"]}\n'.encode('utf-8'),
b'Visit this page again to increment.'
]
status = '200 OK'
headers = [('Content-type', 'text/plain')]
start_response(status, headers)
return response_body
# Configure session options
session_opts = {
'session.type': 'file',
'session.cookie_expires': True,
'session.data_dir': './data/sessions/data',
'session.lock_dir': './data/sessions/lock'
}
# Wrap the WSGI application with SessionMiddleware
application = SessionMiddleware(simple_app, session_opts)
# Run a simple WSGI server
if __name__ == '__main__':
httpd = make_server('', 8000, application)
print("Serving on port 8000...")
print("You can view the application at http://localhost:8000")
try:
httpd.serve_forever()
except KeyboardInterrupt:
print("Shutting down server.")
# To clean up: remove the ./data/sessions directory created by the example.