I'm using Flask-Caching on a REST API.
Flask-Caching uses key request.path
by default, but I want to cache by path, user ID, and URL parameters.
I've did something horrible like this:
def custom_cache_key(params=None, user=None, path=None):
if params and user:
return lambda *args, **kwargs : str(hash(frozenset((path or request.path,frozenset([(param_name, request.args.get(param_name)) for param_name in params]), get_user_id()))))
if params:
return lambda *args, **kwargs : str(hash(frozenset((path or request.path,frozenset([(param_name, request.args.get(param_name)) for param_name in params])))))
if user:
return lambda *args, **kwargs : str(hash(frozenset((path or request.path, get_user_id()))))
return lambda *args, **kwargs : str(hash(frozenset((path or request.path))))
class ActivityHistory(Resource):
@cache.cached(timeout=60, make_cache_key=custom_cache_key(user=True, params=["page"]))
@jwt_required()
def get(self):
user = get_jwt_identity()
page = request.args.get('page', 1)
# ... return user's history, paginated
This allows a customizable cache key to cache based on user ID and/or parameters. When there is a change, I do:
cache.delete(custom_cache_key(user=True, params=["page"])())
When ActivityHistory
is called and page
parameter is null
, cache key is hash of userid and request path.
But, when it's called with ?page=1
, cache key changes, as it should.
The problem is, when that's the case, I cannot delete the caches with parameters, since I don't know the exact parameters.
Is there any solution, like a "path" based caching, "requestpath/userid/parameters"?
I saw Flask-Caching provides a memoized
function but in my case functions do not receive arguments, and even if they did, it seems it's not possible to delete caches without knowing the exact parameters.
Thanks in advance
Already read the documentation, there's no information about this. I expected to use something like:
@cache.cached(timeout=60, cache_keys=[request.path, get_user_id(), get_params(["page"])])
and then, I could do:
cache.delete(["/history", get_user_id()])
# deletes all under this "path", all pages
Maybe dictionary based so more filtering can be done