Package: caches
CachesA Python caching library that gives a similar interface to standard Python data structures like Dict and Set but is backed byRedis.Caches has been used in production for years across many different products, handling millions of requests.How to useCaches relies on setting the environment variableCACHES_DSN:redis://localhost/0If you want to cache things using more than one Redis server, you can actually set multiple environment variables and specify thecaches.interface.Redisclass you want to use:# redis1 uses the standard Redis interface
export CACHES_DSN_1=redis://somedomain.com/0#redis1

# redis2 uses a custom interface child class
export CACHES_DSN_2=custom.interface.Redis://someotherdomain.com/0#redis2After you've set the environment variable, then you just need to import caches in your code:importcachesCaches will take care of parsing the and DSN urls and creating the associated Redis connections automatically, so after importing, Caches will be ready to use.InterfaceAll Caches caching classes have a similar interface, their constructor takes a key and data:c=Cache(['foo','bar','che'])printc.key# foo.bar.cheIf you would like to init your cache object with a value, use thedata**kwarg:c=Cache('foo',data="boom!")printc.key# fooprintc# "boom!"Each Caches base caching class is meant to be extended so you can set some parameters:serialize-- boolean -- True if you want all values pickled, False if you don't (ie, you're caching ints or strings or something).prefix-- string -- This will be prepended to the key args you pass into the constructor.ttl-- integer -- time to live, how many seconds to cache the value. 0 (default) means cache forever.connection_name-- string -- if you have more than one caches DSN then you can use this to set the name of the connection you want (the name of the connection is the#connection_namefragment of a DSN url).classMyIntCache(Cache):serialize=False# don't bother to serialize values since we're storing intsprefix="MyIntCache"# every key will have this prefix, change to invalidate all currently cached valuesttl=7200# store each int for 2 hoursCache ClassesCacheThis is the traditional caching object, it sets a value into a key:c=Cache('foo')c.data=5# cache 5c+=10# increment 5 by 10, store 15 in the cachec.clear()print(c)# NoneDictCacheThis caching object acts more or less like a Pythondictionary:c=DictCache('foo')c['bar']='b'c['che']='c'forkey,valinc.items():print(key,val)# will print "bar b" and then "che c"SetCacheThis caching object acts more or less like a Pythonset:c=SetCache('foo')c.add('bar')c.add('che')print('che'inc)# TrueSortedSetCacheThis caching object acts more or less like a Pythonsetbut has some changes:Theadd()method takes a tuple(score, elem)Thepop()method will pop off the lowest score from the set, and pops a tuple(score, elem)Anrpop()method allows you to pop the highest score from the set.Iterating through the set results in tuples of(score, elem), not just elem like in a normal set or theSetCache.c=SortedSetCache('foo')c.add((1,'bar'))c.add((10,'che'))print('che'inc)# Trueprint(c.pop())# (1, bar)SentinelCacheHandy for gated access:c=SentinelCache('foo')ifnotc:print("sentinel value isn't set so do this")ifnotc:print("sentinel value is now set so this will never run")DecoratorCaches exposes a decorator to make caching the return value of a function easy. This only works forCachederived caching.Thecacheddecorator can accept a caching class and also a key function (similar to the pythonbuilt-insorted()functionkey argument), except caches key argument returns a list that can be passed to the constructor of the caching class as*args.importfunctoolsfromcachesimportCache@Cache.cached(key="some_cache_key")deffoo(*args):returnfunctools.reduce(lambdax,y:x+y,args)foo(1,2)# will compute the value and cache the return valuefoo(1,2)# return value from cachefoo(1,2,3)# uh-oh, wrong value, our key was too staticLet's try again, this time with a dynamic key@Cache.cached(key=lambda*args:args)deffoo(*args):returnfunctools.reduce(lambdax,y:x+y,args)foo(1,2)# compute and cache, key func returned [1, 2]foo(1,2)# grabbed from cachefoo(1,2,3)# compute and cache because our key func returned [1, 2, 3]What about custom caches classes?classCustomCache(Cache):pass@CustomCache.cached(key=lambda*args:args)deffoo(*args):returnfunctools.reduce(lambdax,y:x+y,args)InstallUse pip from pypi:pip install cachesor from source using pip:pip install -U "git+https://github.com/jaymon/caches#egg=caches"