r_cache¶
-
privex.helpers.decorators.
r_cache
(cache_key: Union[str, callable], cache_time=300, format_args: list = None, format_opt: privex.helpers.decorators.FormatOpt = <FormatOpt.POS_AUTO: 'force_pos'>, **opts) → Any[source]¶ This is a decorator which caches the result of the wrapped function with the global cache adapter from
privex.helpers.cache
using the keycache_key
and with an expiry ofcache_time
seconds.Future calls to the wrapped function would then load the data from cache until the cache expires, upon which it will re-run the original code and re-cache it.
To bypass the cache, pass kwarg
r_cache=False
to the wrapped function. To override the cache key on demand, passr_cache_key='mykey'
to the wrapped function.Example usage:
>>> from privex.helpers import r_cache >>> >>> @r_cache('mydata', cache_time=600) ... def my_func(*args, **kwargs): ... time.sleep(60) ... return "done"
This will run the function and take 60 seconds to return while it sleeps
>>> my_func() done
This will run instantly because “done” is now cached for 600 seconds
>>> my_func() done
This will take another 60 seconds to run because
r_cache
is set to False (disables the cache)>>> my_func(r_cache=False) done
Using a dynamic cache_key:
Simplest and most reliable - pass ``r_cache_key`` as an additional kwarg
If you don’t mind passing an additional kwarg to your function, then the most reliable method is to override the cache key by passing
r_cache_key
to your wrapped function.Don’t worry, we remove both
r_cache
andr_cache_key
from the kwargs that actually hit your function.>>> my_func(r_cache_key='somekey') # Use the cache key 'somekey' when caching data for this function
Option 2. Pass a callable which takes the same arguments as the wrapped function
In the example below,
who
takes two arguments:name
andtitle
- we then pass the functionmake_key
which takes the same arguments -r_cache
will detect that the cache key is a function and call it with the same(*args, **kwargs)
passed to the wrapped function.>>> from privex.helpers import r_cache >>> >>> def make_key(name, title): ... return f"mycache:{name}" ... >>> @r_cache(make_key) ... def who(name, title): ... return "Their name is {title} {name}" ...
We can also obtain the same effect with a
lambda
callable defined directly inside of the cache_key.>>> @r_cache(lambda name,title: f"mycache:{name}") ... def who(name, title): ... return "Their name is {title} {name}"
Option 3. Can be finnicky - using ``format_args`` to integrate with existing code
If you can’t change how your existing function/method is called, then you can use the
format_args
feature.NOTE: Unless you’re forcing the usage of kwargs with a function/method, it’s strongly recommended that you keep
force_pos
enabled, and specify both the positional argument ID, and the kwarg name.Basic Example:
>>> from privex.helpers import r_cache >>> import time >>> >>> @r_cache('some_cache:{}:{}', cache_time=600, format_args=[0, 1, 'x', 'y']) ... def some_func(x=1, y=2): ... time.sleep(5) ... return 'x + y = {}'.format(x + y) >>>
Using positional arguments, we can see from the debug log that it’s formatting the
{}:{}
in the key withx:y
>>> some_func(1, 2) 2019-08-21 06:58:29,823 lg DEBUG Trying to load "some_cache:1:2" from cache 2019-08-21 06:58:29,826 lg DEBUG Not found in cache, or "r_cache" set to false. Calling wrapped function. 'x + y = 3' >>> some_func(2, 3) 2019-08-21 06:58:34,831 lg DEBUG Trying to load "some_cache:2:3" from cache 2019-08-21 06:58:34,832 lg DEBUG Not found in cache, or "r_cache" set to false. Calling wrapped function. 'x + y = 5'
When we passed
(1, 2)
and(2, 3)
it had to re-run the function for each. But once we re-call it for the previously ran(1, 2)
- it’s able to retrieve the cached result just for those args.>>> some_func(1, 2) 2019-08-21 06:58:41,752 lg DEBUG Trying to load "some_cache:1:2" from cache 'x + y = 3'
Be warned that the default format option
POS_AUTO
will make kwargs’ values be specified in the same order as they were listed informat_args
>>> some_func(y=1, x=2) # ``format_args`` has the kwargs in the order ``['x', 'y']`` thus ``.format(x,y)`` 2019-08-21 06:58:58,611 lg DEBUG Trying to load "some_cache:2:1" from cache 2019-08-21 06:58:58,611 lg DEBUG Not found in cache, or "r_cache" set to false. Calling wrapped function. 'x + y = 3'
- Parameters
format_opt (FormatOpt) – (default:
FormatOpt.POS_AUTO
) “Format option” - how should args/kwargs be used when filling placeholders in thecache_key
(see comments on FormatOption)format_args (list) – A list of positional arguments numbers (e.g.
[0, 1, 2]
) and/or kwargs['x', 'y', 'z']
that should be used to format the cache_keycache_key (str) – The cache key to store the cached data into, e.g. mydata
cache_time (int) – The amount of time in seconds to cache the result for (default: 300 seconds)
whitelist (bool) – (default:
True
) If True, only use specified arg positions / kwarg keys when formattingcache_key
placeholders. Otherwise, trust whatever args/kwargs were passed to the func.
- Return Any res
The return result, either from the wrapped function, or from the cache.