If you have used Flask and are in need of caching views, then you will be familiar with Flask-cache. Flask-cache provides you with a very simple interface in order to setup cache for your application.
Flask-cache extension provides you with a way to set a specific time-out for your view function when you enable cache for that view as follows.
@cache.cached(timeout=50) def index(): return render_template('index.html')
But it does not provide you the ability to set time-outs dynamically. I came across a use case where I was calling a view function with different parameters and wanted the view to be cached until a fixed specific time and in my case it was midnight.
Below is the implementation of the cached decorator in Flask-cache
def cached(self, timeout=None, key_prefix='view/%s', unless=None): def decorator(f): @functools.wraps(f) def decorated_function(*args, **kwargs): .... if rv is None: rv = f(*args, **kwargs) try: self.cache.set(cache_key, rv, timeout=decorated_function.cache_timeout) .... decorated_function.uncached = f decorated_function.cache_timeout = timeout decorated_function.make_cache_key = make_cache_key return decorated_function return decorator
You can see that the decorator directly passes the
timeout parameter as a parameter to the
cache.set function. So this removes the possibility of passing a function to dynamically set the timeout.
So I decided to write a decorator which decorates the
cached decorator. Below is the decorator function I wrote that sets the time-out to 23:59 hours.
def cache_timeout(f): @functools.wraps(f) def decorated_function(*args, **kwargs): now = datetime.datetime.now() deadline = now.replace(hour=23, minute=59) period = (deadline - now) f.cache_timeout = period.seconds return f(*args, **kwargs) return decorated_function
cache_timeout decorator can then be used as
@app.route('/stats', methods=['GET']) @cache_timeout @cache.cached() def stats(): return render_template('index.html')
Please note that location of
@cache.cached() cannot be interchanged.
Currently the decorator does not accept any parameters, but it can be easily extended to include parameters and perform cache time-out operations to your satisfaction.