import functools import time from collections import OrderedDict class LRUCache: def __init__(self, max_size, expiry_hours): self.cache = OrderedDict() self.max_size = max_size self.expiry_seconds = expiry_hours * 3600 def __setitem__(self, key, value): now = time.time() self.cache[key] = (value, now + self.expiry_seconds) while len(self.cache) > self.max_size: self.cache.popitem(last=False) def __getitem__(self, key): value, expiry_time = self.cache[key] now = time.time() if now > expiry_time: del self.cache[key] raise KeyError return value def get(self, key, default=None): try: return self[key] except KeyError: return default def lru_cache(max_size=128, expiry_hours=1): cache = LRUCache(max_size, expiry_hours) def decorator(func): @functools.wraps(func) def wrapper(*args, **kwargs): key = (args, frozenset(kwargs.items())) if key in cache.cache: return cache[key] result = func(*args, **kwargs) cache[key] = result return result return wrapper return decorator # Example: @lru_cache(max_size=100, expiry_hours=8) def slow_hello_world(): response = time.sleep(10) return "Hello world!"