flask-cache
flask-cache copied to clipboard
Include query string parameters in cache key
A really common use case for caching is that the result of an API call will change depending on query string parameters given.
Right now query parameters are being ignored: https://github.com/thadeusb/flask-cache/blob/master/flask_cache/init.py#L308
I hack around this by adding stuff to key_prefix, but it seems like this might be desirable as a default - I can't think of a situation where you'd add a query parameter to a URL and expect a different result.
A counterargument is that some things randomly add query parameters to URLs, like google analytics (utm_source etc), which will cause double caching. So we could solve that by either creating a blacklist (where we may miss things, but is simpler from a developer point of view) or by creating a whitelist (where it's probably more correct, as long as the developer remembers to add the GET params they use).
Is there any interest in this? I can take a shot at implementing it.
+1 also if user is loged or not
yes - should check for flask-login or you can pass a user class...
Very simple to add I would think?
+1 needed this right now!
defeinitely interested! Flask-Login and get parameters support would be great
With recent versions of Flask-cache, you can simulate it like this:
def make_key ():
"""Make a key that includes GET parameters."""
return request.full_path
@app.route('/hello')
@cache.cached(key_prefix=make_key)
def view_hello():
return "Hello, " + request.args.get('name')
Put anything you want in make_key().
Sorry - I see that @makmanalp already mentioned key_prefix in the original issue. I do agree that full_path would be a better default, but in my app, I'll probably always need a custom key_prefix anyway.
Hi,
Is this a good idea : ?
import hashlib
from flask import request
def func_cache_with_args(func_name, **kwargs):
"""Return hash value from func name and request.full_path
Ex: my_view + /api/v1/sdmx/INSEE/data/IPCH-2015-FR-COICOP/A.07120.?startPeriod=2011
"""
return hashlib.sha256(func_name.encode("utf-8") + request.full_path.encode("utf-8")).hexdigest()
@cache.memoize(360, make_name=func_cache_with_args)
def my_view(flowRef, key=None, providerRef=None, version="all"):
...
@srault95 Well, I think this may be a bit of a tangent to the original ticket. I don't see anything wrong with that, but there's a tradeoff in hashing cache keys. You're obscuring what the keys mean, and thus maybe getting rid of the capability to nuke only part of the cache by filtering through existing keys based on some rule (e.g. only the v2 api keys) - short of some other mechanism that either can enumerate all cached things or stores categories of keys elsewhere.
A little addition/modification to @davidmegginson's contribution:
def make_key_prefix():
"""Make a key that includes GET parameters."""
return url_for(request.endpoint, **request.args)
url_for
seems to order request.args
in the resultant URL, preventing double caching of urls with shuffled querystring params/args.
And for view functions with view_args:
def make_key_prefix():
"""Make a key that includes GET parameters and view/route args."""
args = {**request.view_args, **request.args}
return url_for(request.endpoint, **args)
Just cutting the path for this discussion, it is already 'natively' implemented on Flask, through method memoize().
As described in documentation, cache.memoize()
considers the function parameters, on the contrary of cache.cached()
.
I think it's implemented in https://github.com/sh4nks/flask-caching/pull/35
just wanted to confirm that using query_string=True
as @eyalev said works.