flask-cache también memoriza los parámetros de la cadena de consulta de URL

La extensión flask-cache tiene un decorador @cache.memoize para almacenar en caché una vista que incluye los **kwargs *args y **kwargs . Sin embargo, algunas de mis vistas también toman una cadena de consulta de URL, por ejemplo /foo/image?width=640 . El decorador agrega un método make_cache_key a la función de vista decorada que se puede usar para personalizar la clave de caché

Sin embargo, no sé cómo obtener el request.args fuera del contexto de solicitud normal.

¿Alguna idea de cómo hacer que @cache.memoize funcione también con cadenas de consulta de URL?

Related of "flask-cache también memoriza los parámetros de la cadena de consulta de URL"

Hoy tuve el mismo problema y no encontré ningún ejemplo en Internet, así que jugué un poco.

Este es mi make_cache_key:

 def make_cache_key(*args, **kwargs): path = request.path args = str(hash(frozenset(request.args.items()))) lang = get_locale() return (path + args + lang).encode('utf-8') 

Podría usar request.url en lugar de path y el argumento hash. Necesitaba agregar el idioma de los usuarios a la clave también.

Cachear una vista:

 @app.route("/test") @cache.cached(timeout=50) def test(): a = request.args.get('a') b = request.args.get('b') return a + b test.make_cache_key = make_cache_key 

Funciona pero creo que es algo engorroso. Resultó que el prefijo clave puede ser invocable, lo que genera la clave de caché completa. Por lo tanto podemos hacer esto:

 @app.route("/test2") @cache.cached(timeout=50, key_prefix=make_cache_key) def test2(): a = request.args.get('a') b = request.args.get('b') return a + b 

Se me ocurrió esto y aún no lo he usado en producción, por lo que puede que no funcione en todos los casos.

Puede utilizar flask-caching :

Continuación de la extensión Flask-Cache

Con lo que puedes hacer algo como esto:

 @app.route("/") @cache.cached(timeout=10, query_string=True) def index(): return render_template('index.html') 

Documentos del código fuente :

 :param query_string: Default False. When True, the cache key used will be the result of hashing the ordered query string parameters. This avoids creating different caches for the same query just because the parameters were passed in a different order. See _make_cache_key_query_string() for more details. 

Desde la versión 0.3.4, key_prefix puede ser invocable:

Nuevo en la versión 0.3.4: Opcionalmente, puede ser un llamable que no toma argumentos pero devuelve una cadena que se utilizará como la clave de caché.

Aquí está el doc: Flask-Cache

Gracias a Smoe y Asdine El Hrychy , aquí está mi versión; genera una clave para la URL actual + cadena de consulta (que, en mi opinión, debe ser una necesidad común).

Nota:

  • la cadena de consulta se ordena en un bash de permanecer igual si solicita ?a=foo&b=bar o ?b=bar&a=foo (inicialmente hice (k, v) for k, val in flask.request.args.viewitems() for v in sorted(val) pero cambié para ordenar las claves también)
  • admite la misma clave con varias apariciones, es decir ?a=foo&a=bar (y devolverá la misma clave que ?a=bar&a=foo )
  • key_prefix argumento key_prefix es solo para cached y no para memoize , al menos a partir de Flask-Cache 0.13.1, y como toma la ruta de la URL, debe encajar en la mayoría de los memoize uso de memoize

El código:

 import flask import urllib def cache_key(): args = flask.request.args key = flask.request.path + '?' + urllib.urlencode([ (k, v) for k in sorted(args) for v in sorted(args.getlist(k)) ]) return key # ... import time @app.route('/test') @cache.cached(timeout=600, key_prefix=cache_key) def test(): return time.time() @app.route('//test') @cache.cached(timeout=3600, key_prefix=cache_key) def value_test(value): return flask.jsonify(time=time.time(), value=value) 

ya que no quiero que el propio hermano haga más trabajo como citar los argumentos, pero el siguiente código puede funcionar y puede satisfacer mi requisito:

 from flask import request def cache_key(): return request.url @main.route("/test/", methods=['GET']) @cache.cached(timeout=10, key_prefix=cache_key) def do_somthing(): return "hello %s" % str(request.args)