48 lines
1.6 KiB
Python
48 lines
1.6 KiB
Python
"""Modulo que contiene la clase/decorador Cache"""
|
|
import json
|
|
import logging
|
|
from blake3 import blake3 # pylint: disable=no-name-in-module
|
|
from django.core.cache import cache
|
|
|
|
_log = logging.getLogger(__name__)
|
|
_log.addHandler(logging.NullHandler())
|
|
|
|
|
|
class Cache:
|
|
""" Decorator that caches the result of a function
|
|
|
|
It works by generating a key given the function signature and uses it to store the result
|
|
of the function on redis, so if the function is called with the same parameters again it
|
|
will be cached and will retrieve the data from redis and will not execute the function.
|
|
|
|
It is assumed that the function will returns a dictionary that can be formatted to json.
|
|
"""
|
|
|
|
# Time to expire, by default a week
|
|
expire = 60 * 60 * 24 * 7
|
|
|
|
def __init__(self, function):
|
|
self.function = function
|
|
|
|
def __call__(self, *args, **kwargs):
|
|
_log.info('Caching function %s with argument list %s and dictionary %s',
|
|
self.function.__name__, args, kwargs)
|
|
|
|
key = f'{self.function.__name__}:{self.create_hash_key(args, kwargs)}'
|
|
_log.debug('Resolved key for function is "%s"', key)
|
|
|
|
if cache.ttl(key) != 0:
|
|
_log.info('Key was in cache')
|
|
result = json.loads(cache.get(key))
|
|
return result
|
|
|
|
_log.info('Key was not in cache')
|
|
result = self.function(*args, **kwargs)
|
|
cache.set(key, json.dumps(result), timeout=self.expire)
|
|
return result
|
|
|
|
@staticmethod
|
|
def create_hash_key(args, kwargs):
|
|
"""Crea la key dados unos argumentos arbitrarios"""
|
|
return blake3((str(args) + str(kwargs)).encode('utf-8')).hexdigest()
|