dimagi / quickcache

caching has never been easier
BSD 3-Clause "New" or "Revised" License
9 stars 3 forks source link

quickcache: caching has never been easier

Usage

quickcache has an easy default for Django, but it's just as easy to bring your own backend.

BYOB:

from quickcache import get_quickcache

quickcache = get_quickcache(cache=my_cache_backend)

Django:

First add the following to your settings.py - updating the backend/locations of the caches as you see fit. Both 'locmem' and 'default' must be present for the django integration to work.

CACHES = {
    'locmem': {
        'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
        'LOCATION': 'locmem-cache',
    },
    'default': {
        'BACKEND': 'django.core.cache.backends.redis.RedisCache',
        'LOCATION': 'redis://localhost:6379',
    }
}

Then use the cache as follows:

from quickcache.django_quickcache import get_django_quickcache

quickcache = get_django_quickcache(memoize_timeout=10, timeout=5 * 60)

...and then lets you cache any function based on the values of some or all of its params

@quickcache(['name'])
def take_expensive_action(name):
    ...

...or any method based on values of the self object

class Person(object):
    ...
    @quickcache(['self.id'])
    def look_up_friends(self):
        ...

... and when you know you just made the cache stale, you can clear it

person.add_friend()
person.look_up_friends.clear(person)

Examples

Features

A note on backends

The Django default uses a two-tier caching backend that caches in memory as well as in the default shared cache. This is optimized for multi-worker web code so that within a single request the object is cached in memory, and across requests the object is cached in the shared cache.

If you are using your own backend, you can achieve the same effect using quickcache's cache helpers, TieredCache and CacheWithTimeout. If you are rolling your own, you may want to work off the source code in quickcache/django_quickcache.py.

In the examples above, the keyword arguments timeout and memoize_timeout are only available on the Django default; when you bring your own backend, and want to override your system-wide default timeout, the equivalent will be to override the cache with the cache keyword argument. For example,

@quickcache(..., cache=get_my_cache_backend_with_timeout(timeout=TIMEOUT))

where get_my_cache_backend_with_timeout is a function you define.

Note on unicode and strings in vary_on

When strings and unicode values are used as vary on parameters they will result in the same cache key if and only if the string values are UTF-8 or ascii encoded. e.g. u'namé' and 'nam\xc3\xa9' (UTF-8 encoding) will result in the same cache key BUT u'namé' and 'nam\xe9' (latin-1 encoding) will NOT result in the same cache key

Building and deployment

Following instructions for packaging and distributing universal wheels

python setup.py bdist_wheel
pip install twine
twine upload dist/*