├── .gitignore ├── LICENSE.txt ├── README.md ├── django_cache_decorator ├── __init__.py └── utils.py ├── setup.cfg ├── setup.py └── tests.py /.gitignore: -------------------------------------------------------------------------------- 1 | django_cache_decorator.egg-info 2 | dist 3 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Richard Caceres 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Easily add caching to functions within a django project. 2 | 3 | 4 | ## Installation from PyPi 5 | 6 | ``` 7 | pip install django-cache-decorator 8 | ``` 9 | 10 | 11 | ## Installation from Github 12 | 13 | ``` 14 | pip install -e git+https://github.com/rchrd2/django-cache-decorator.git#egg=django-cache-decorator 15 | ``` 16 | 17 | 18 | ## Example usage 19 | 20 | ``` 21 | @django_cache_decorator(time=0) 22 | def geocodeGooglePlaceTextJson(location): 23 | ... 24 | ``` 25 | 26 | 27 | ## Running tests 28 | 29 | ``` 30 | python -m unittest tests 31 | ``` 32 | 33 | 34 | ## Credits 35 | 36 | Built off of example code from: 37 | http://james.lin.net.nz/2011/09/08/python-decorator-caching-your-functions/ 38 | 39 | Further development and packaging by Richard Caceres (@rchrd2) 40 | 41 | 42 | ## Release log 43 | 44 | - 0.4 - Update project for PyPi (pip install django-cache-decorator)! 45 | - 0.3 - another bug fix for unicode params 46 | - 0.2 - bug fix for unicode params 47 | - 0.1 - initial release -------------------------------------------------------------------------------- /django_cache_decorator/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from __future__ import absolute_import 3 | from __future__ import unicode_literals 4 | 5 | # This can be used to cache the results of functions. 6 | # 7 | # Example: 8 | # @django_cache_decorator(time=0) 9 | # def geocodeGooglePlaceTextJson(location): 10 | # ... 11 | # 12 | # Built off of code form: 13 | # http://james.lin.net.nz/2011/09/08/python-decorator-caching-your-functions/ 14 | 15 | 16 | 17 | # load logging 18 | #import logging 19 | #logger = logging.getLogger(__name__) 20 | 21 | from django_cache_decorator.utils import cache_get_key 22 | 23 | 24 | # New cache instance reconnect-apparently 25 | cache_factory = {} 26 | 27 | def get_cache_factory(cache_type): 28 | """ 29 | Helper to only return a single instance of a cache 30 | As of django 1.7, may not be needed. 31 | """ 32 | from django.core.cache import get_cache 33 | 34 | if cache_type is None: 35 | cache_type = 'default' 36 | 37 | if not cache_type in cache_factory: 38 | cache_factory[cache_type] = get_cache(cache_type) 39 | 40 | return cache_factory[cache_type] 41 | 42 | 43 | def django_cache_decorator(time=300, cache_key='', cache_type=None): 44 | """ 45 | Easily add caching to a function in django 46 | """ 47 | 48 | if cache_type is None: 49 | cache_type = 'memcache' 50 | 51 | cache = get_cache_factory(cache_type) 52 | if not cache_key: 53 | cache_key = None 54 | 55 | def decorator(fn): 56 | def wrapper(*args, **kwargs): 57 | #logger.debug([args, kwargs]) 58 | 59 | # Inner scope variables are read-only so we set a new var 60 | _cache_key = cache_key 61 | 62 | if not _cache_key: 63 | _cache_key = cache_get_key(fn.__name__, *args, **kwargs) 64 | 65 | #logger.debug(['_cach_key.......',_cache_key]) 66 | 67 | result = cache.get(_cache_key) 68 | 69 | if not result: 70 | result = fn(*args, **kwargs) 71 | cache.set(_cache_key, result, time) 72 | 73 | return result 74 | return wrapper 75 | 76 | return decorator 77 | 78 | -------------------------------------------------------------------------------- /django_cache_decorator/utils.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from __future__ import unicode_literals 3 | 4 | import hashlib 5 | 6 | def cache_get_key(*args, **kwargs): 7 | serialise = [] 8 | for arg in args: 9 | serialise.append(unicode(arg)) 10 | for key,arg in kwargs.items(): 11 | serialise.append(unicode(key)) 12 | serialise.append(unicode(arg)) 13 | 14 | full_str = u"".join(serialise).encode('utf-8') 15 | key = hashlib.md5(full_str).hexdigest() 16 | return key -------------------------------------------------------------------------------- /setup.cfg: -------------------------------------------------------------------------------- 1 | [metadata] 2 | description-file = README.md -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup 2 | 3 | version = '0.4' 4 | 5 | setup( 6 | name = 'django-cache-decorator', 7 | packages = ['django_cache_decorator'], 8 | license = 'MIT', 9 | version = version, 10 | description = 'Easily add caching to functions within a django project.', 11 | long_description=open('README.md').read(), 12 | author = 'Richard Caceres', 13 | author_email = 'me@rchrd.net', 14 | url = 'https://github.com/rchrd2/django-cache-decorator/', 15 | download_url = 'https://github.com/rchrd2/django-cache-decorator/tarball/' + version, 16 | keywords = ['django','caching','decorator'], 17 | classifiers = [], 18 | ) 19 | -------------------------------------------------------------------------------- /tests.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from __future__ import absolute_import 3 | from __future__ import unicode_literals 4 | 5 | import unittest 6 | 7 | from django_cache_decorator import utils 8 | 9 | class UtilsTestCase(unittest.TestCase): 10 | 11 | def setUp(self): 12 | pass 13 | 14 | 15 | def test_get_cache_key(self): 16 | args = [ 17 | 'Čakovec, Croatia', 18 | ], 19 | kwargs = { 20 | 'test': 'test', 21 | 'test2': 'Čakovec, Croatia', 22 | } 23 | 24 | key = utils.cache_get_key('testFunctionName', *args, **kwargs) 25 | 26 | --------------------------------------------------------------------------------