Created
October 3, 2025 10:16
-
-
Save musoftware/dfac25c6dd20538516c2bd8765c6430e to your computer and use it in GitHub Desktop.
In-Memory Cache Decorator with TTL Expiration
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import time | |
| from functools import wraps | |
| class TTLCache: | |
| """ | |
| A decorator that caches the results of a function for a specified TTL. | |
| """ | |
| def __init__(self, ttl_seconds=300): | |
| """ | |
| Initializes the decorator with a TTL in seconds. | |
| """ | |
| self.ttl = ttl_seconds | |
| self.cache = {} | |
| def __call__(self, func): | |
| @wraps(func) | |
| def wrapper(*args, **kwargs): | |
| # Create a unique key based on the function's arguments. | |
| # Note: This simple keying strategy works for hashable arguments. | |
| # For complex objects, a more robust serialization (like json.dumps) might be needed. | |
| key = str(args) + str(sorted(kwargs.items())) | |
| if key in self.cache: | |
| result, timestamp = self.cache[key] | |
| age = time.time() - timestamp | |
| if age < self.ttl: | |
| print(f"CACHE HIT for '{func.__name__}'. Returning cached data (age: {age:.2f}s).") | |
| return result | |
| else: | |
| print(f"CACHE EXPIRED for '{func.__name__}'.") | |
| del self.cache[key] | |
| print(f"CACHE MISS for '{func.__name__}'. Calling the original function.") | |
| result = func(*args, **kwargs) | |
| self.cache[key] = (result, time.time()) | |
| return result | |
| return wrapper | |
| # --- Example Usage --- | |
| # Use the decorator with a 5-second TTL. | |
| @TTLCache(ttl_seconds=5) | |
| def fetch_weather_data(city: str): | |
| """Simulates a slow API call to fetch weather data.""" | |
| print(f"--- Making a slow API call for {city}... ---") | |
| time.sleep(2) # Simulate network latency | |
| # In a real app, this would be a requests.get() call | |
| return f"Weather for {city}: 25°C, Sunny" | |
| if __name__ == "__main__": | |
| # First call: is a CACHE MISS, takes 2 seconds | |
| print(fetch_weather_data("Suez")) | |
| # Second call (within 5 seconds): is a CACHE HIT, is instantaneous | |
| print(fetch_weather_data("Suez")) | |
| # Wait for the cache to expire | |
| print("\n... Waiting for 6 seconds for cache to expire ...\n") | |
| time.sleep(6) | |
| # Third call (after 5 seconds): is a CACHE EXPIRED/MISS, takes 2 seconds again | |
| print(fetch_weather_data("Suez")) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment