Skip to content

Commit

Permalink
Add Redis storage support
Browse files Browse the repository at this point in the history
  • Loading branch information
DonDebonair committed Sep 12, 2017
1 parent 1e73548 commit 3b70503
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 3 deletions.
37 changes: 37 additions & 0 deletions machine/storage/backends/redis.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
from urllib.parse import urlparse
from redis import StrictRedis

from machine.storage.backends.base import MachineBaseStorage


class RedisStorage(MachineBaseStorage):
def __init__(self, settings):
super().__init__(settings)
self._key_prefix = settings.get('REDIS_KEY_PREFIX', 'SM')
url = urlparse(settings['REDIS_URL'])
if hasattr(url, "path"):
db = url.path[1:]
else:
db = 0
max_connections = settings.get('REDIS_MAX_CONNECTIONS', None)
self._redis = StrictRedis(host=url.hostname, port=url.port, db=db,
password=url.password, max_connections=max_connections)

def _prefix(self, key):
return "{}:{}".format(self._key_prefix, key)

def has(self, key):
return self._redis.exists(self._prefix(key))

def get(self, key):
return self._redis.get(self._prefix(key))

def set(self, key, value, expires=None):
self._redis.set(self._prefix(key), value, expires)

def delete(self, key):
self._redis.delete(self._prefix(key))

def size(self):
info = self._redis.info('memory')
return info['used_memory']
3 changes: 2 additions & 1 deletion requirements-dev.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,5 @@ twine~=1.5
coverage~=4.4
pytest-cov~=2.5
Sphinx~=1.6
sphinx-autobuild~=0.7
sphinx-autobuild~=0.7
redis~=2.10
7 changes: 5 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,11 @@ def run(self):
author_email=about["__email__"],
setup_requires=['pytest-runner'],
tests_require=['pytest', 'pytest-cov', 'coverage'],
install_requires=dependencies,
python_requires='~=3.3',
extras_require={
'redis': ['redis', 'hiredis']
},
classifiers=[
"Development Status :: 3 - Alpha",
"Intended Audience :: Developers",
Expand All @@ -92,8 +97,6 @@ def run(self):
"Topic :: Office/Business"
],
keywords='slack bot framework ai',
install_requires=dependencies,
python_requires='~=3.3',
entry_points={
'console_scripts': [
'slack-machine = machine.bin.run:main',
Expand Down
40 changes: 40 additions & 0 deletions tests/test_redis_storage.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
from unittest.mock import MagicMock

import pytest
from redis import StrictRedis

from machine.storage.backends.redis import RedisStorage

@pytest.fixture
def redis_client():
return MagicMock(spec=StrictRedis)

@pytest.fixture
def redis_storage(mocker, redis_client):
mocker.patch('machine.storage.backends.redis.StrictRedis', autospec=True)
settings = {'REDIS_URL': 'redis://nohost:1234'}
storage = RedisStorage(settings)
storage._redis = redis_client
return storage

def test_set(redis_storage, redis_client):
redis_storage.set('key1', 'value1')
redis_client.set.assert_called_with('SM:key1', 'value1', None)
redis_storage.set('key2', 'value2', 42)
redis_client.set.assert_called_with('SM:key2', 'value2', 42)

def test_get(redis_storage, redis_client):
redis_storage.get('key1')
redis_client.get.assert_called_with('SM:key1')

def test_has(redis_storage, redis_client):
redis_storage.has('key1')
redis_client.exists.assert_called_with('SM:key1')

def test_delete(redis_storage, redis_client):
redis_storage.delete('key1')
redis_client.delete.assert_called_with('SM:key1')

def test_size(redis_storage, redis_client):
redis_storage.size()
redis_client.info.assert_called_with('memory')

0 comments on commit 3b70503

Please sign in to comment.