Use Beaker session with Flask

Flask is a great web (micro)framework for Python. But it’s default session implementation is a little too weak to some applications, especially when you need to save more than a few bytes in the session. Beaker is a powerful web session library, but Flask is not friendly to switch session manager.

After some tweaking, I found the clean way to do this. Instead of using beaker’s SessionMiddleware, which makes the session environment request.environ[‘beaker.session’], instead of the nature “session”, I used MixIn pattern. Now it’s just a bunch of code, maybe later I can make it a real extension.

Here comes the code.

#!/usr/bin/env python
# -*- coding: utf-8 -*-
from beaker.session import Session, SessionObject
from flask import Flask, request, session

class BeakerMixin(object):
    beaker_opts = {'type':'file', 'data_dir':'sessions', 'timeout':3600,
        'auto':True, 'cookie_expires':True, 'invalidate_corrupt':True}

    def open_session(self, request):
        return SessionObject(request.environ, key=self.session_cookie_name,
            **self.beaker_opts)

    def save_session(self, session, response):
        if session.accessed():
            session.persist()
            data = session.__dict__['_headers']
            if data['set_cookie'] and data['cookie_out']:
                response.headers['Set-Cookie'] = data['cookie_out']

class BeakerSessionFlask(BeakerMixin, Flask): pass

app = BeakerSessionFlask('test_beaker')

@app.route('/')
def index():
    try: session['cpt'] += 1
    except KeyError: session['cpt'] = 1
    return 'sid: %s, cpt: %d' % (session.id, session['cpt'])

if __name__ == '__main__':
    # app.secret_key is not required
    app.run(host='0.0.0.0', port=8080, debug=True)

One Comment on “Use Beaker session with Flask”

  1. matejcik说道:

    thanks for the code.
    There is another way to accomplish something similar, by using the “g” object and “before_request”/”teardown_request” callbacks : http://flask.pocoo.org/docs/tutorial/dbcon/
    you can assign “g.session” with every request. This does not replace the default sessions, but it’s comfortable too


留下评论