Skip to content

Instantly share code, notes, and snippets.

@spjwebster
Created May 8, 2014 08:13
Show Gist options
  • Save spjwebster/90c0b1d7dff68c0ab692 to your computer and use it in GitHub Desktop.
Save spjwebster/90c0b1d7dff68c0ab692 to your computer and use it in GitHub Desktop.
Redis-based session handler for Flask
# Set session handler
app.session_interface = RedisSessionInterface()
import logging
import pickle
from datetime import timedelta
from uuid import uuid4
from redis import Redis
from werkzeug.datastructures import CallbackDict
from flask.sessions import SessionInterface, SessionMixin
class RedisSession(CallbackDict, SessionMixin):
def __init__(self, initial=None, sid=None, new=False):
def on_update(self):
self.modified = True
CallbackDict.__init__(self, initial, on_update)
self.sid = sid
self.new = new
self.modified = False
def __str__(self):
return 'RedisSession<' + self.sid + '>';
def __unicode__(self):
return u'RedisSession<' + self.sid + u'>';
def __nonzero__(self):
return True
class RedisSessionInterface(SessionInterface):
serializer = pickle
session_class = RedisSession
def __init__(self, redis=None, prefix='session:'):
self.logger = logging.getLogger(__name__)
if redis is None:
redis = Redis()
self.redis = redis
self.prefix = prefix
def generate_sid(self):
return str(uuid4())
def get_redis_expiration_time(self, app, session):
if session.permanent:
return app.permanent_session_lifetime
return timedelta(days=1)
def open_session(self, app, request):
sid = request.cookies.get(app.session_cookie_name)
if not sid:
sid = self.generate_sid()
return self.session_class(sid=sid, new=True)
val = self.redis.get(self.prefix + sid)
if val is not None:
data = self.serializer.loads(val)
return self.session_class(data, sid=sid)
return self.session_class(sid=sid, new=True)
def save_session(self, app, session, response):
domain = self.get_cookie_domain(app)
if session:
redis_exp = self.get_redis_expiration_time(app, session)
cookie_exp = self.get_expiration_time(app, session)
val = self.serializer.dumps(dict(session))
self.redis.setex(
self.prefix + session.sid, val,
int(redis_exp.total_seconds())
)
response.set_cookie(
app.session_cookie_name,
session.sid,
expires=cookie_exp,
httponly=True,
domain=domain
)
else:
self.redis.delete(self.prefix + session.sid)
if session.modified:
response.delete_cookie(
app.session_cookie_name,
domain=domain
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment