Skip to content

Instantly share code, notes, and snippets.

@musoftware
Created October 3, 2025 10:16
Show Gist options
  • Select an option

  • Save musoftware/dfac25c6dd20538516c2bd8765c6430e to your computer and use it in GitHub Desktop.

Select an option

Save musoftware/dfac25c6dd20538516c2bd8765c6430e to your computer and use it in GitHub Desktop.
In-Memory Cache Decorator with TTL Expiration
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