"""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()