Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions Pipfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
[[source]]
url = "https://pypi.org/simple"
verify_ssl = true
name = "pypi"

[packages]
redis = "*"
pymemcache = "*"
pytest = "*"
pytest-cov = "*"

[dev-packages]

[requires]
python_version = "3.7"
136 changes: 136 additions & 0 deletions Pipfile.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 10 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,13 @@ Install using pip: `$ pip install cache4py`

### Usage
```python
from cache4py import cache, LRU, Backend
from cache4py.decorators import cache
from cache4py.storage.backends import RedisBackend

# You can choose memcached, redis or default (python's dict) as a backend.
redis_backend = Backend(variant=Backend.REDIS, url='', port='')
redis_backend = RedisBackend(url='localhost', port='6379')

@cache(eviction_policy=LRU, backend=redis_backend)
@cache(backend=redis_backend)
def my_function_one(*args, **kwargs):
# do something awesome
return
Expand Down Expand Up @@ -42,11 +43,15 @@ pip install -r requirements.txt
```
### Running the tests

Run unit tests using the command: `TODO`
Run unit tests using the command:

```
pytest --cov=cache4py --cov-report html tests/
```

## Issue tracking

Create issues at [cache4pd/issues](https://github.com/nitinl/cache4py/issues).
Create issues at [cache4py/issues](https://github.com/nitinl/cache4py/issues).

## Authors

Expand Down
5 changes: 5 additions & 0 deletions cache4py/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
"""
Author: nitin
Date: 18/7/17
Description:
"""
44 changes: 44 additions & 0 deletions cache4py/decorators.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
"""
Author: nitin
Date: 18/7/17
Description:
"""
from functools import wraps

from cache4py.exceptions import BackendException
from cache4py.utils import args_to_key, hash_key
from cache4py.storage.redis import RedisBackend


def cache(backend=RedisBackend, keys=args_to_key):
"""
Cache decorator. Backend can be a python dict, redis or memcached server.
"""

def _decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
if backend is None:
backend_exception_message = 'Invalid input None provided for backend.'
raise BackendException(backend_exception_message)

key = keys(*args, **kwargs)
hashed_key = hash_key(key)

result = backend.get(hashed_key)

if result is not None:
# cache hit
return result

# cache miss
function_result = func(*args, **kwargs)

# store result in cache
backend.set(hashed_key, function_result)
return function_result

return wrapper

return _decorator

21 changes: 21 additions & 0 deletions cache4py/exceptions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
"""
Author: nitin
Date: 18/7/17
Description:
"""


class Cache4PyException(Exception):
pass


class BackendException(Cache4PyException):
pass


class RedisBackendException(BackendException):
pass


class MemcachedBackendException(BackendException):
pass
5 changes: 5 additions & 0 deletions cache4py/storage/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
"""
Author: nitin
Date: 19/10/18
Description:
"""
41 changes: 41 additions & 0 deletions cache4py/storage/base.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
"""
Author: nitin
Date: 19/10/18
Description: Base class for all storage interfaces
"""
import abc


class BaseBackend(metaclass=abc.ABCMeta):
"""
Abstract class defining Cache client interface. All implementations of cache clients
must extend this class.
"""

@abc.abstractmethod
def get(self, key_name):
"""
Return the value at key ``key_name``, or None if the key doesn't exist.
:param key_name: A key.
:return: Value at key ``key_name``, or None if the key doesn't exist.
"""
raise NotImplementedError('Cache client must define a get method.')

@abc.abstractmethod
def set(self, key_name, value):
"""
Set the value at key ``key_name`` to ``value``
:param key_name: A key object.
:param value: A value object.
:return: True if set successfully else False.
"""
raise NotImplementedError('Cache client must define a set method.')

@abc.abstractmethod
def delete(self, key_name):
"""
Deletes key specified by ``key_name``.
:param key_name: A key object.
:return: True if key is successfully deleted else False. Failure can mean connection issue or no value at given key in db.
"""
raise NotImplementedError('Cache client must define a delete method.')
Loading