memoize cache python redis flask-restful flask-cache cache-invalidation

python - memoize - Cómo usar Flask-Cache con Flask-Restful



flask caching memoize (4)

¿Cómo uso Flask-Cache @ cache.cached () decorator con Flask-Restful? Por ejemplo, tengo una clase que Foo heredó de Resource, y Foo tiene los métodos de obtención, publicación, colocación y eliminación.

¿Cómo puedo invalidar los resultados en caché después de un POST ?

@api.resource(''/whatever'') class Foo(Resource): @cache.cached(timeout=10) def get(self): return expensive_db_operation() def post(self): update_db_here() ## How do I invalidate the value cached in get()? return something_useful()


Como la implementación de Flask-Cache no le da acceso al objeto de cache subyacente, tendrá que crear una instancia explícita de un cliente Redis y usar su método de keys (enumerar todas las claves de caché).

  • El método cache_key se usa para anular la generación de clave predeterminada en su decorador cache.cached .
  • El método clear_cache borrará solo la parte del caché correspondiente al recurso actual.

Esta es una solución que se probó solo para Redis y la implementación probablemente diferirá un poco cuando se use un motor de caché diferente.

from app import cache # The Flask-Cache object from config import CACHE_REDIS_HOST, CACHE_REDIS_PORT # The Flask-Cache config from redis import Redis from flask import request import urllib redis_client = Redis(CACHE_REDIS_HOST, CACHE_REDIS_PORT) def cache_key(): args = request.args key = request.path + ''?'' + urllib.urlencode([ (k, v) for k in sorted(args) for v in sorted(args.getlist(k)) ]) return key @api.resource(''/whatever'') class Foo(Resource): @cache.cached(timeout=10, key_prefix=cache_key) def get(self): return expensive_db_operation() def post(self): update_db_here() self.clear_cache() return something_useful() def clear_cache(self): # Note: we have to use the Redis client to delete key by prefix, # so we can''t use the ''cache'' Flask extension for this one. key_prefix = request.path keys = [key for key in redis_client.keys() if key.startswith(key_prefix)] nkeys = len(keys) for key in keys: redis_client.delete(key) if nkeys > 0: log.info("Cleared %s cache keys" % nkeys) log.info(keys)




##create a decarator from werkzeug.contrib.cache import SimpleCache CACHE_TIMEOUT = 300 cache = SimpleCache() class cached(object): def __init__(self, timeout=None): self.timeout = timeout or CACHE_TIMEOUT def __call__(self, f): def decorator(*args, **kwargs): response = cache.get(request.path) if response is None: response = f(*args, **kwargs) cache.set(request.path, response, self.timeout) return response return decorator #add this decarator to your views like below @app.route(''/buildingTotal'',endpoint=''buildingTotal'') @cached() def eventAlert(): return ''something'' @app.route(''/buildingTenants'',endpoint=''buildingTenants'') @cached() def buildingTenants(): return ''something''