title: Unable to use caching on a python flask routing everytime the cache is reinitialized
body: <p>I am trying to create a simple flask application with a custom cache implementaiton.</p>
  <p>The code goes like this</p>
  <pre><code>from flask import Flask, request, Response
  
  app = Flask(__name__)
  
  class CustomLRUCache:
      &quot;&quot;&quot; Implementation for LRU cache with time based eviction.
  
          items are evicted based on the time limit and using the size of the cache.
  
          The cache can be used as a decorator or using the get method.
          The `get` method accepts any arbitrary function, but on the parameters are
          considered in the key, so it is advisable not to mix function.
  
          &gt;&gt;&gt; cache = CustomLRUCache(5)
          &gt;&gt;&gt; def foo(i):
          ...     return i + 1
  
          &gt;&gt;&gt; cache.get(foo, 1)  # runs foo
          &gt;&gt;&gt; cache.get(foo, 1)  # returns the previously calculated result
  
          As a decorator is more familiar:
  
          &gt;&gt;&gt; @CustomLRUCache(5)
          ... def foo(i):
          ...     return i + 1
  
          &gt;&gt;&gt; foo(1)  # runs foo
          &gt;&gt;&gt; foo(1)  # returns the previously calculated result
  
  
          Either method can allow for fine-grained control of the cache:
  
          &gt;&gt;&gt; local_cache = CustomLRUCache(5)
          &gt;&gt;&gt; @local_cache
          ... def foo(i):
          ...     return i + 1
  
          &gt;&gt;&gt; local_cache.clear_cache()  # resets the cache (clear every item)
          &gt;&gt;&gt; local_cache.prune()  # clear invalid items
      &quot;&quot;&quot;
      _items: Dict[int, Tuple[datetime, Any]]
      _recently_added: List[int]
  
      delta: timedelta
      max_size: int
  
      def __init__(self, seconds: Optional[int] = None, max_size: Optional[int] = None):
          self.delta = timedelta(seconds=seconds) if seconds else None
          self.max_size = max_size
  
          self._items = {}
          self._recently_added = []
  
      def __call__(self, func):
          @wraps(func)
          def wrapper(*args, **kwargs):
              return self.get(func, args, kwargs)
  
          return wrapper
  
      @staticmethod
      def _get_key(args, kwargs) -&gt; int:
          &quot;&quot;&quot; Get the thing we're going to use to lookup items in the cache. &quot;&quot;&quot;
          key = (args, tuple(sorted(kwargs.items())))
          return int(hashlib.md5(' '.join(map(str, key)).encode('utf-8')).hexdigest(), 16)
  
      def _update(self, key: int, item: Any) -&gt; None:
          &quot;&quot;&quot; Make sure an item is up to date. &quot;&quot;&quot;
          if key in self._recently_added:
              self._recently_added.remove(key)
          # the first item in the list is the least recently used
          self._recently_added.append(key)
          self._items[key] = (datetime.now() + self.delta, item)
  
          # when this function is called, something has changed, so we can also sort out the cache
          self.prune()
  
      def prune(self):
          &quot;&quot;&quot; Clear out everything that no longer belongs in the cache
  
              First delete everything that has expired. Then delete everything that isn't recent (only
              if there is a `max_size`).
          &quot;&quot;&quot;
          # clear out anything that no longer belongs in the cache.
          current_time = datetime.now()
          # first get rid of things which have expired
          for key, (expiry, item) in self._items.items():
              if expiry &lt; current_time:
                  del self._items[key]
                  self._recently_added.remove(key)
          # then make sure there aren't too many recent items
          if self.max_size:
              self._recently_added[:-self.max_size] = []
  
      def clear_cache(self):
          &quot;&quot;&quot; Clear everything from the cache &quot;&quot;&quot;
          self._items = {}
          self._recently_added = []
  
      def get(self, func, args, kwargs):
          &quot;&quot;&quot; Given a function and its arguments, get the result using the cache
  
              Get the key from the arguments of the function. If the key is in the cache, and the
              expiry time of that key hasn't passed, return the result from the cache.
  
              If the key *has* expired, or there are too many &quot;recent&quot; items, recalculate the result,
              add it to the cache, and then return the result.
          &quot;&quot;&quot;
          key = self._get_key(args, kwargs)
          current_time = datetime.now()
          if key in self._recently_added:
              # there is something in the cache
              expiry, item = self._items.get(key)
              if expiry &lt; current_time:
                  # the item has expired, so we need to get the new value
                  print(&quot;data being loaded again&quot;)
                  new_item = func(*args, **kwargs)
                  self._update(key, new_item)
                  return new_item
              else:
                  # we can use the existing value
                  print(&quot;Data coming from cache&quot;)
                  return item
          else:
              # never seen this before, so add it
              new_item = func(*args, **kwargs)
              self._update(key, new_item)
              return new_item
  
  
  cache = CustomLRUCache(seconds=3600, max_size=20)
  
  def foo(a):
      return a+1
  
  
  @app.route('/health', methods=['GET'])
  def ping_health():
      print(cache.get(foo, 1, {}))
      return &quot;UP&quot;
  
  
  if __name__ == '__main__':
      app.run(debug=True, host=&quot;0.0.0.0&quot;, port=8080)
  </code></pre>
  <p>Everytime I hit the <code>/health</code> route in the 1 hour time limit for which the cache is active I expect the data to be returned from cache. But everytime I hit the <code>/health</code> route I end up getting the data from the function call instead of cache. Am I missing something very basic here? How do I achieve this? The same program works fine standalone when I access the elements from cache as below.</p>
  <pre><code>from time import sleep
  
  from CustomLRUCache import CustomLRUCache
  
  cache = CustomLRUCache(seconds=4, max_size=2)
  
  
  # @CustomLRUCache(seconds=2, max_size=2)
  def return_data(a):
      print(&quot;From function...&quot;)
      return a * 1
  
  
  print(cache.get(return_data, (5,), {}))
  sleep(2)
  print(cache.get(return_data, (5,), {}))
  </code></pre>
  <p>From the above code when I execute it I get the data from cache instead of loading it everytime from function.</p>