tags:

views:

381

answers:

6

I'm looking for a Python caching library but can't find anything so far. I need a simple dict-like interface where I can set keys and their expiration and get them back cached. Sort of something like:

cache.get(myfunction, duration=300)

which will give me the item from the cache if it exists or call the function and store it if it doesn't or has expired. Does anyone know something like this?

+7  A: 

Take a look at Beaker:

Corbin March
Ah, I kept searching for this and all I found was a wiki that mentioned how to use it as an WSGI middleware. It looks like what I need, thank you.
Stavros Korokithakis
+3  A: 

I think the python memcached API is the prevalent tool, but I haven't used it myself and am not sure whether it supports the features you need.

David Berger
That one's the industry standard, but all I want is a simple in-memory storage mechanism that can hold 100 keys or so, and memcached is a bit overkill. Thank you for the answer, though.
Stavros Korokithakis
+2  A: 
import time

class CachedItem(object):
    def __init__(self, key, value, duration=60):
        self.key = key
        self.value = value
        self.duration = duration
        self.timeStamp = time.time()

    def __repr__(self):
        return '<CachedItem {%s:%s} expires at: %s>' % (self.key, self.value, time.time() + self.duration)

class CachedDict(dict):

    def get(self, key, fn, duration):
        if key not in self \
            or self[key].timeStamp + self[key].duration < time.time():
                print 'adding new value'
                o = fn(key)
                self[key] = CachedItem(key, o, duration)
        else:
            print 'loading from cache'

        return self[key].value



if __name__ == '__main__':

    fn = lambda key: 'value of %s  is None' % key

    ci = CachedItem('a', 12)
    print ci 
    cd = CachedDict()
    print cd.get('a', fn, 5)
    time.sleep(2)
    print cd.get('a', fn, 6)
    print cd.get('b', fn, 6)
    time.sleep(2)
    print cd.get('a', fn, 7)
    print cd.get('b', fn, 7)
Tzury Bar Yochay
I did something like that, but you need locks for multithreading and a size parameter to avoid it growing infinitely. Then you need some function to sort the keys by accesses to discard the least-accessed ones, etc etc...
Stavros Korokithakis
A: 

You might also take a look at the Memoize decorator. You could probably get it to do what you want without too much modification.

tgray
A: 

Look at gocept.cache

A: 

Look at bda.cache http://pypi.python.org/pypi/bda.cache - uses ZCA and is tested with zope and bfg.

Jens W. Klein