from functools import wraps from flask import request, jsonify import time class Cache: def __init__(self): """ Simple caching mechanism that will only cache data if the user is not sending any GET / POST arguments in the request. Use in combination with the RouteProvider class to be able to include in a request without extra instantiation and reduce performance cost. """ self.cache = {} def __call__(self, timeout): """ Can be expanded to include request payload based caching - make a caching hash which includes the request.args and request.form data. Keep in mind that it is memory taxing given a dynamic request type. Caching large payload routes with thousands of possible arguments could cause a memory overflow and crash the server. """ def decorator(func): @wraps(func) def wrapper(*args, **kwargs): cache_key = f"{request.method}:{request.path}" if (cache_key in self.cache and time.time() <= self.cache[cache_key]["date_expires"]) and not ( request.form.keys() or request.args.keys() ): return jsonify(self.cache[cache_key]["data"]) else: data = func(*args, **kwargs) expiration_time = time.time() + timeout self.cache[cache_key] = { "date_created": time.time(), "date_expires": expiration_time, "data": data } return jsonify(data) return wrapper return decorator _cache = Cache()