Skip to content

Instantly share code, notes, and snippets.

@alejandrobernardis
Last active March 3, 2016 09:17
Show Gist options
  • Select an option

  • Save alejandrobernardis/5244661 to your computer and use it in GitHub Desktop.

Select an option

Save alejandrobernardis/5244661 to your computer and use it in GitHub Desktop.
Python // Tornado Session // ref: `pycket` => https://github.com/diogobaeder/pycket
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# Copyright (c) 2013 Asumi Kamikaze Inc.
# Copyright (c) 2013 The Octopus Apps Inc.
# Licensed under the Apache License, Version 2.0 (the "License")
#
# Author: Alejandro M. Bernardis
# Email: alejandro.m.bernardis at gmail.com
# Created: 3/8/13, 3:03 AM
import os
import sys
def load_dependencies():
pkg = '/test'
external_library = '/development/library/python'
root_path = os.path.dirname(__file__)
sys.path.insert(0, external_library)
sys.path.insert(0, root_path.replace(pkg, '/bin'))
sys.path.insert(0, root_path.replace(pkg, '/lib'))
sys.path.insert(0, root_path.replace(pkg, '/src'))
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# Copyright (c) 2013 Asumi Kamikaze Inc.
# Copyright (c) 2013 The Octopus Apps Inc.
# Licensed under the Apache License, Version 2.0 (the "License")
#
# Author: Alejandro M. Bernardis
# Email: alejandro.m.bernardis at gmail.com
# Created: 3/17/13, 9:26 PM
class ConfigurationError(Exception):
pass
class SessionExpireError(Exception):
pass
class SessionError(Exception):
pass
## PICKLE
"(dp1\nS'key-28'\np2\nS'value-28'\np3\nsS'key-29'\np4\nS'value-29'\np5\nsS'key-22'\np6\nS'value-22'\np7\nsS'key-23'\np8\nS'value-23'\np9\nsS'key-20'\np10\nS'value-20'\np11\nsS'key-21'\np12\nS'value-21'\np13\nsS'key-26'\np14\nS'value-26'\np15\nsS'key-27'\np16\nS'value-27'\np17\nsS'key-24'\np18\nS'value-24'\np19\nsS'key-25'\np20\nS'value-25'\np21\nsS'key-39'\np22\nS'value-39'\np23\nsS'key-38'\np24\nS'value-38'\np25\nsS'key-31'\np26\nS'value-31'\np27\nsS'key-30'\np28\nS'value-30'\np29\nsS'key-33'\np30\nS'value-33'\np31\nsS'key-32'\np32\nS'value-32'\np33\nsS'key-35'\np34\nS'value-35'\np35\nsS'key-34'\np36\nS'value-34'\np37\nsS'key-37'\np38\nS'value-37'\np39\nsS'key-36'\np40\nS'value-36'\np41\nsS'key-88'\np42\nS'value-88'\np43\nsS'key-89'\np44\nS'value-89'\np45\nsS'key-84'\np46\nS'value-84'\np47\nsS'key-85'\np48\nS'value-85'\np49\nsS'key-86'\np50\nS'value-86'\np51\nsS'key-87'\np52\nS'value-87'\np53\nsS'key-80'\np54\nS'value-80'\np55\nsS'key-81'\np56\nS'value-81'\np57\nsS'key-82'\np58\nS'value-82'\np59\nsS'key-83'\np60\nS'value-83'\np61\nsS'key-99'\np62\nS'value-99'\np63\nsS'key-98'\np64\nS'value-98'\np65\nsS'key-93'\np66\nS'value-93'\np67\nsS'key-92'\np68\nS'value-92'\np69\nsS'key-91'\np70\nS'value-91'\np71\nsS'key-90'\np72\nS'value-90'\np73\nsS'key-97'\np74\nS'value-97'\np75\nsS'key-96'\np76\nS'value-96'\np77\nsS'key-95'\np78\nS'value-95'\np79\nsS'key-94'\np80\nS'value-94'\np81\nsS'key-13'\np82\nS'value-13'\np83\nsS'key-12'\np84\nS'value-12'\np85\nsS'key-11'\np86\nS'value-11'\np87\nsS'key-10'\np88\nS'value-10'\np89\nsS'key-17'\np90\nS'value-17'\np91\nsS'key-16'\np92\nS'value-16'\np93\nsS'key-15'\np94\nS'value-15'\np95\nsS'key-14'\np96\nS'value-14'\np97\nsS'key-19'\np98\nS'value-19'\np99\nsS'key-18'\np100\nS'value-18'\np101\nsS'key-3'\np102\nS'value-3'\np103\nsS'key-2'\np104\nS'value-2'\np105\nsS'key-1'\np106\nS'value-1'\np107\nsS'key-0'\np108\nS'value-0'\np109\nsS'key-7'\np110\nS'value-7'\np111\nsS'key-6'\np112\nS'value-6'\np113\nsS'key-5'\np114\nS'value-5'\np115\nsS'key-4'\np116\nS'value-4'\np117\nsS'key-9'\np118\nS'value-9'\np119\nsS'key-8'\np120\nS'value-8'\np121\nsS'key-66'\np122\nS'value-66'\np123\nsS'key-67'\np124\nS'value-67'\np125\nsS'key-64'\np126\nS'value-64'\np127\nsS'key-65'\np128\nS'value-65'\np129\nsS'key-62'\np130\nS'value-62'\np131\nsS'key-63'\np132\nS'value-63'\np133\nsS'key-60'\np134\nS'value-60'\np135\nsS'key-61'\np136\nS'value-61'\np137\nsS'key-68'\np138\nS'value-68'\np139\nsS'key-69'\np140\nS'value-69'\np141\nsS'key-75'\np142\nS'value-75'\np143\nsS'key-74'\np144\nS'value-74'\np145\nsS'key-77'\np146\nS'value-77'\np147\nsS'key-76'\np148\nS'value-76'\np149\nsS'key-71'\np150\nS'value-71'\np151\nsS'key-70'\np152\nS'value-70'\np153\nsS'key-73'\np154\nS'value-73'\np155\nsS'key-72'\np156\nS'value-72'\np157\nsS'key-79'\np158\nS'value-79'\np159\nsS'key-78'\np160\nS'value-78'\np161\nsS'key-40'\np162\nS'value-40'\np163\nsS'key-41'\np164\nS'value-41'\np165\nsS'key-42'\np166\nS'value-42'\np167\nsS'key-43'\np168\nS'value-43'\np169\nsS'key-44'\np170\nS'value-44'\np171\nsS'key-45'\np172\nS'value-45'\np173\nsS'key-46'\np174\nS'value-46'\np175\nsS'key-47'\np176\nS'value-47'\np177\nsS'key-48'\np178\nS'value-48'\np179\nsS'key-49'\np180\nS'value-49'\np181\nsS'key-59'\np182\nS'value-59'\np183\nsS'key-58'\np184\nS'value-58'\np185\nsS'key-57'\np186\nS'value-57'\np187\nsS'key-56'\np188\nS'value-56'\np189\nsS'key-55'\np190\nS'value-55'\np191\nsS'key-54'\np192\nS'value-54'\np193\nsS'key-53'\np194\nS'value-53'\np195\nsS'key-52'\np196\nS'value-52'\np197\nsS'key-51'\np198\nS'value-51'\np199\nsS'key-50'\np200\nS'value-50'\np201\ns."
## JSON
"{\"key-28\": \"value-28\", \"key-29\": \"value-29\", \"key-22\": \"value-22\", \"key-23\": \"value-23\", \"key-20\": \"value-20\", \"key-21\": \"value-21\", \"key-26\": \"value-26\", \"key-27\": \"value-27\", \"key-24\": \"value-24\", \"key-25\": \"value-25\", \"key-39\": \"value-39\", \"key-38\": \"value-38\", \"key-31\": \"value-31\", \"key-30\": \"value-30\", \"key-33\": \"value-33\", \"key-32\": \"value-32\", \"key-35\": \"value-35\", \"key-34\": \"value-34\", \"key-37\": \"value-37\", \"key-36\": \"value-36\", \"key-88\": \"value-88\", \"key-89\": \"value-89\", \"key-84\": \"value-84\", \"key-85\": \"value-85\", \"key-86\": \"value-86\", \"key-87\": \"value-87\", \"key-80\": \"value-80\", \"key-81\": \"value-81\", \"key-82\": \"value-82\", \"key-83\": \"value-83\", \"key-99\": \"value-99\", \"key-98\": \"value-98\", \"key-93\": \"value-93\", \"key-92\": \"value-92\", \"key-91\": \"value-91\", \"key-90\": \"value-90\", \"key-97\": \"value-97\", \"key-96\": \"value-96\", \"key-95\": \"value-95\", \"key-94\": \"value-94\", \"key-13\": \"value-13\", \"key-12\": \"value-12\", \"key-11\": \"value-11\", \"key-10\": \"value-10\", \"key-17\": \"value-17\", \"key-16\": \"value-16\", \"key-15\": \"value-15\", \"key-14\": \"value-14\", \"key-19\": \"value-19\", \"key-18\": \"value-18\", \"key-3\": \"value-3\", \"key-2\": \"value-2\", \"key-1\": \"value-1\", \"key-0\": \"value-0\", \"key-7\": \"value-7\", \"key-6\": \"value-6\", \"key-5\": \"value-5\", \"key-4\": \"value-4\", \"key-9\": \"value-9\", \"key-8\": \"value-8\", \"key-66\": \"value-66\", \"key-67\": \"value-67\", \"key-64\": \"value-64\", \"key-65\": \"value-65\", \"key-62\": \"value-62\", \"key-63\": \"value-63\", \"key-60\": \"value-60\", \"key-61\": \"value-61\", \"key-68\": \"value-68\", \"key-69\": \"value-69\", \"key-75\": \"value-75\", \"key-74\": \"value-74\", \"key-77\": \"value-77\", \"key-76\": \"value-76\", \"key-71\": \"value-71\", \"key-70\": \"value-70\", \"key-73\": \"value-73\", \"key-72\": \"value-72\", \"key-79\": \"value-79\", \"key-78\": \"value-78\", \"key-40\": \"value-40\", \"key-41\": \"value-41\", \"key-42\": \"value-42\", \"key-43\": \"value-43\", \"key-44\": \"value-44\", \"key-45\": \"value-45\", \"key-46\": \"value-46\", \"key-47\": \"value-47\", \"key-48\": \"value-48\", \"key-49\": \"value-49\", \"key-59\": \"value-59\", \"key-58\": \"value-58\", \"key-57\": \"value-57\", \"key-56\": \"value-56\", \"key-55\": \"value-55\", \"key-54\": \"value-54\", \"key-53\": \"value-53\", \"key-52\": \"value-52\", \"key-51\": \"value-51\", \"key-50\": \"value-50\"}"
## MSGPACK
"\xde\x00d\xa6key-28\xa8value-28\xa6key-29\xa8value-29\xa6key-22\xa8value-22\xa6key-23\xa8value-23\xa6key-20\xa8value-20\xa6key-21\xa8value-21\xa6key-26\xa8value-26\xa6key-27\xa8value-27\xa6key-24\xa8value-24\xa6key-25\xa8value-25\xa6key-39\xa8value-39\xa6key-38\xa8value-38\xa6key-31\xa8value-31\xa6key-30\xa8value-30\xa6key-33\xa8value-33\xa6key-32\xa8value-32\xa6key-35\xa8value-35\xa6key-34\xa8value-34\xa6key-37\xa8value-37\xa6key-36\xa8value-36\xa6key-88\xa8value-88\xa6key-89\xa8value-89\xa6key-84\xa8value-84\xa6key-85\xa8value-85\xa6key-86\xa8value-86\xa6key-87\xa8value-87\xa6key-80\xa8value-80\xa6key-81\xa8value-81\xa6key-82\xa8value-82\xa6key-83\xa8value-83\xa6key-99\xa8value-99\xa6key-98\xa8value-98\xa6key-93\xa8value-93\xa6key-92\xa8value-92\xa6key-91\xa8value-91\xa6key-90\xa8value-90\xa6key-97\xa8value-97\xa6key-96\xa8value-96\xa6key-95\xa8value-95\xa6key-94\xa8value-94\xa6key-13\xa8value-13\xa6key-12\xa8value-12\xa6key-11\xa8value-11\xa6key-10\xa8value-10\xa6key-17\xa8value-17\xa6key-16\xa8value-16\xa6key-15\xa8value-15\xa6key-14\xa8value-14\xa6key-19\xa8value-19\xa6key-18\xa8value-18\xa5key-3\xa7value-3\xa5key-2\xa7value-2\xa5key-1\xa7value-1\xa5key-0\xa7value-0\xa5key-7\xa7value-7\xa5key-6\xa7value-6\xa5key-5\xa7value-5\xa5key-4\xa7value-4\xa5key-9\xa7value-9\xa5key-8\xa7value-8\xa6key-66\xa8value-66\xa6key-67\xa8value-67\xa6key-64\xa8value-64\xa6key-65\xa8value-65\xa6key-62\xa8value-62\xa6key-63\xa8value-63\xa6key-60\xa8value-60\xa6key-61\xa8value-61\xa6key-68\xa8value-68\xa6key-69\xa8value-69\xa6key-75\xa8value-75\xa6key-74\xa8value-74\xa6key-77\xa8value-77\xa6key-76\xa8value-76\xa6key-71\xa8value-71\xa6key-70\xa8value-70\xa6key-73\xa8value-73\xa6key-72\xa8value-72\xa6key-79\xa8value-79\xa6key-78\xa8value-78\xa6key-40\xa8value-40\xa6key-41\xa8value-41\xa6key-42\xa8value-42\xa6key-43\xa8value-43\xa6key-44\xa8value-44\xa6key-45\xa8value-45\xa6key-46\xa8value-46\xa6key-47\xa8value-47\xa6key-48\xa8value-48\xa6key-49\xa8value-49\xa6key-59\xa8value-59\xa6key-58\xa8value-58\xa6key-57\xa8value-57\xa6key-56\xa8value-56\xa6key-55\xa8value-55\xa6key-54\xa8value-54\xa6key-53\xa8value-53\xa6key-52\xa8value-52\xa6key-51\xa8value-51\xa6key-50\xa8value-50"
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# Copyright (c) 2013 Asumi Kamikaze Inc.
# Copyright (c) 2013 The Octopus Apps Inc.
# Licensed under the Apache License, Version 2.0 (the "License")
#
# Author: Alejandro M. Bernardis
# Email: alejandro.m.bernardis at gmail.com
# Created: 2/22/13, 6:34 PM
try:
import cPickle as pickle
except ImportError:
import pickle
try:
import msgpack
except ImportError:
msgpack = None
try:
import json
except ImportError:
json = None
from mx.proc3ss.common.errors import ConfigurationError
from uuid import uuid4
__all__ = ['Session', 'SessionMixin', 'create_mixin', 'REDIS_ENGINE',
'MEMCACHED_ENGINE', 'PICKLE_FORMAT', 'MSGPACK_FORMAT', 'JSON_FORMAT']
#: - engines -
REDIS_ENGINE = 'redis'
MEMCACHED_ENGINE = 'memcached'
#: - Serialization -
PICKLE_FORMAT = 'pickle'
MSGPACK_FORMAT = 'msgpack'
JSON_FORMAT = 'json'
#: - configratios -
SESSION_NAME = 'sid'
SESSION_PREFIX = 'session'
SESSION_EXPIRE = 24 * 60 * 60
REDIS_CLIENT_DB = 0
REDIS_CLIENT_ARGS = ['host', 'port', 'db', 'password', 'socket_timeout',
'connection_pool', 'charset', 'errors', 'decode_responses',
'unix_socket_path', 'max_connections']
MEMCACHED_CLIENT_ARGS = ['servers', 'debug', 'pickleProtocol', 'pickler',
'unpickler', 'pload', 'pid', 'server_max_key_length',
'server_max_value_length', 'dead_retry',
'socket_timeout', 'cache_cas']
class Client(object):
def __init__(self, settings):
self._settings = settings
self._create()
@property
def client(self):
if not hasattr(self, '_client'):
self._client = self._create()
return self._client
@property
def serializer(self):
if not hasattr(self, '_serializer'):
self._serializer = self._settings.get('serializer', PICKLE_FORMAT)
return self._serializer
def get(self, sid):
session = self._do_get(sid)
return self._deserialize(session) if session else {}
def save(self, sid, value, expire=None):
if not expire and 'expire' in self._settings:
expire = self._settings['expire']
session = self._serialize(value)
self._do_save(sid, session, expire or SESSION_EXPIRE)
def delete(self, sid):
self._do_delete(sid)
def _create(self):
raise NotImplementedError()
def _do_get(self, sid):
raise NotImplementedError()
def _do_save(self, sid, value, expire):
raise NotImplementedError()
def _do_delete(self, sid):
raise NotImplementedError()
def _serialize(self, value):
if json and self.serializer == JSON_FORMAT:
return json.dumps(value)
elif msgpack and self.serializer == MSGPACK_FORMAT:
return msgpack.packb(value)
return pickle.dumps(value)
def _deserialize(self, value):
if json and self.serializer == JSON_FORMAT:
return json.loads(value)
elif msgpack and self.serializer == MSGPACK_FORMAT:
return msgpack.unpackb(value)
return pickle.loads(value)
class RedisClient(Client):
def _create(self):
from redis import Redis, ConnectionPool
settings = self._settings.copy()
settings['db'] = REDIS_CLIENT_DB
for key in self._settings:
if key not in REDIS_CLIENT_ARGS:
del settings[key]
if 'max_connections' in settings:
pool_settings = settings.copy()
del settings['max_connections']
settings['connection_pool'] = ConnectionPool(**pool_settings)
self._client = Redis(**settings)
def _do_get(self, sid):
return self.client.get(sid)
def _do_save(self, sid, value, expire):
self.client.set(sid, value)
self.client.expire(sid, expire)
def _do_delete(self, sid):
self.client.delete(sid)
def __repr__(self):
settings = self._settings
return '<%s host="%s" port="%s">' % \
(self.__class__.__name__, settings['host'], settings['port'])
class MemcachedClient(Client):
def _create(self):
from memcache import Client as Memcached
settings = self._settings.copy()
for key in self._settings:
if key not in MEMCACHED_CLIENT_ARGS:
del settings[key]
self._client = Memcached(**settings)
def _do_get(self, sid):
return self.client.get(sid)
def _do_save(self, sid, value, expire):
self.client.set(sid, value, expire)
def _do_delete(self, sid):
self.client.delete(sid)
def __repr__(self):
settings = self._settings
return '<%s host="%s" port="%s">' % \
(self.__class__.__name__, settings['host'], settings['port'])
class ClientFactory(object):
@staticmethod
def create(settings):
if 'engine' not in settings:
raise ConfigurationError('Engine not define.')
engine = settings['engine']
client = getattr(ClientFactory, '_create_%s' % engine, None)
if not client:
raise ConfigurationError('Engine "%s" is not supported.' % engine)
return client(settings)
@staticmethod
def _create_redis(settings):
return RedisClient(settings)
@staticmethod
def _create_memcached(settings):
return MemcachedClient(settings)
class Session(object):
def __init__(self, handler):
self._handler = handler
@property
def settings(self):
if not hasattr(self, '_settings'):
if 'session' not in self._handler.settings:
raise ConfigurationError(
'Session configurations is not define.')
settings = self._handler.settings.copy()
self._settings = settings['session']
return self._settings
@property
def client(self):
if not hasattr(self, '_client'):
self._client = ClientFactory.create(self.settings)
return self._client
@property
def data(self):
return self.client.get(self.sid)
@property
def is_empty(self):
return not self.data
@property
def keys(self):
return self.data.keys()
@property
def iterkeys(self):
return iter(self.data)
@property
def sid(self):
sid = self._handler.get_secure_cookie(SESSION_NAME)
return sid or self._set_sid()
def get(self, key, default=None):
session = self.data
if key not in session:
raise KeyError('%s not found in session' % key)
return session.get(key, default)
def set(self, key, value):
session = self.data
session[key] = value
self._save_data(session)
def update(self, **kwargs):
session = self.data
session.update(kwargs)
self._save_data(session)
def delete(self, *keys):
session = self.data
for key in keys:
if key in session:
del session[key]
self._save_data(session)
def clear(self):
self._save_data({})
def expire(self, value):
self._save_data(self.data, value)
def has_key(self, key):
return key in self.data
def _save_data(self, value, expire=None):
self.client.save(self.sid, value, expire)
def _set_sid(self):
cookie = self.settings.get('cookie', {})
cookie.setdefault('expires', None)
cookie.setdefault('expires_days', None)
self._handler.set_secure_cookie(SESSION_NAME, str(uuid4()), **cookie)
class SessionMixin(object):
@property
def session(self):
return create_mixin(self, '_session', Session)
def create_mixin(context, property, cls):
if not hasattr(context, property):
setattr(context, property, cls(context))
return getattr(context, property)
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# Copyright (c) 2013 Asumi Kamikaze Inc.
# Copyright (c) 2013 The Octopus Apps Inc.
# Licensed under the Apache License, Version 2.0 (the "License")
#
# Author: Alejandro M. Bernardis
# Email: alejandro.m.bernardis at gmail.com
# Created: 3/15/13, 6:00 PM
from base import load_dependencies
load_dependencies()
try:
import unittest
import time
from mx.proc3ss.web.auth import Identity
from mx.proc3ss.web.sessions import REDIS_ENGINE, RedisClient, \
MEMCACHED_ENGINE, MemcachedClient, ClientFactory, Session, \
SessionMixin, MSGPACK_FORMAT, JSON_FORMAT
from tornado.testing import LogTrapTestCase, AsyncHTTPTestCase
from tornado.web import Application, RequestHandler, HTTPError
from uuid import uuid4
except:
exit(u'Los módulos no fueron encontrados.')
#: --
user_data = dict(
uid=1,
username='sysadmin',
rid=1 << 32,
rolename='admin',
email='sysadmin@localhost',
enabled=True,
available=True
)
GENERIC_RESPONSE = 'Success'
GENERIC_ERROR = 'Error'
#: --
class ClientsTest(unittest.TestCase):
key = 'client-test'
obj = dict(a=1,b=2,c=3,d=4)
cfg_redis = dict(engine=REDIS_ENGINE)
cfg_memcached = dict(engine=MEMCACHED_ENGINE, servers=['127.0.0.1:11211'])
def test_00_factory(self):
c = ClientFactory.create(self.cfg_redis)
c.save(self.key, self.obj)
self.assertEqual(c.get(self.key), self.obj)
c.delete(self.key)
self.assertNotEqual(c.get(self.key), self.obj)
self.assertEqual(c.get(self.key), {})
self.assertEqual(c.get('undefined'), {})
c = ClientFactory.create(self.cfg_memcached)
c.save(self.key, self.obj)
self.assertEqual(c.get(self.key), self.obj)
c.delete(self.key)
self.assertNotEqual(c.get(self.key), self.obj)
self.assertEqual(c.get(self.key), {})
self.assertEqual(c.get('undefined'), {})
def test_01_redis(self):
c = RedisClient(self.cfg_redis)
c.save(self.key, self.obj)
self.assertEqual(c.get(self.key), self.obj)
c.delete(self.key)
self.assertNotEqual(c.get(self.key), self.obj)
self.assertEqual(c.get(self.key), {})
self.assertEqual(c.get('undefined'), {})
def test_02_memcached(self):
c = MemcachedClient(self.cfg_memcached)
c.save(self.key, self.obj)
self.assertEqual(c.get(self.key), self.obj)
c.delete(self.key)
self.assertNotEqual(c.get(self.key), self.obj)
self.assertEqual(c.get(self.key), {})
self.assertEqual(c.get('undefined'), {})
class BaseHandler(RequestHandler, SessionMixin):
def initialize(self):
self._current_user = user_data.copy()
@property
def identity(self):
if not hasattr(self,'_identity'):
self._identity = Identity(self.current_user)
return self._identity
def get_secure_cookie(self, name, value=None, max_age_days=31):
if not hasattr(self, '_cookie_sid'):
self._cookie_sid = str(uuid4())
return 'cookie-sid-test-01' # self._cookie_sid
def get(self):
assert isinstance(self.session, Session)
assert self.session.is_empty
self.session.set('first-name', 'Alejandro')
assert not self.session.is_empty
assert self.session.get('first-name') == 'Alejandro'
self.session.clear()
assert self.session.keys == []
assert self.session.is_empty
assert not self.session.data
self.session.set('first-name', 'Alejandro')
assert self.session.get('first-name') == 'Alejandro'
self.session.update(test='ok!')
assert self.session.has_key('test')
assert self.session.keys == ['test', 'first-name']
self.session.delete('test')
assert not self.session.has_key('test')
assert self.session.keys == ['first-name']
self.session.expire(1)
time.sleep(2)
assert self.session.is_empty
self.session.expire(24 * 60 * 60)
for i in range(0, 100):
self.session.set('key-%s' % i, 'value-%s' % i)
self.finish(GENERIC_RESPONSE)
class RedisHandler(BaseHandler):
def initialize(self):
self.settings['session'] = dict(
engine=REDIS_ENGINE, serializer=MSGPACK_FORMAT)
if hasattr(self, '_session'):
del self._session
class MemcachedHandler(RedisHandler):
def initialize(self):
self.settings['session'] = dict(
engine=MEMCACHED_ENGINE, servers=['127.0.0.1:11211'])
if hasattr(self, '_session'):
del self._session
@property
def session(self):
if not hasattr(self, '_session'):
self._session = Session(self)
return self._session
class RequestHandlerTest(AsyncHTTPTestCase, LogTrapTestCase):
def get_app(self):
handlers = [
('/redis', RedisHandler),
('/memcached', MemcachedHandler)
]
settings = dict()
settings['cookie_secret'] = "SeCuR3 C00k1e! #.#"
return Application(handlers, **settings)
def get_url_response(self, url='/', follow_redirects=False):
self.http_client.fetch(self.get_url(url), self.stop,
follow_redirects=follow_redirects)
return self.wait()
def test_01_redis(self):
response = self.get_url_response('/redis')
self.assertEqual(response.code, 200)
self.assertEqual(response.buffer.read(), GENERIC_RESPONSE)
def test_02_memcached(self):
response = self.get_url_response('/memcached')
self.assertEqual(response.code, 200)
self.assertEqual(response.buffer.read(), GENERIC_RESPONSE)
if __name__ == '__main__':
unittest.main(verbosity=2)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment