docs: def cached(key, timeout=3600):
      """Cache the return value of the decorated function with the given key.
  
      Key can be a String or a function.
      If key is a function, it must have the same arguments as the decorated function,
      otherwise it cannot be called successfully.
      """
  
      def decorator(f):
          @wraps(f)
          def wrapped(*args, **kwargs):
              cache = get_cache()
              # Check if key is a function
              if callable(key):
                  cache_key = key(*args, **kwargs)
              else:
                  cache_key = key
              # Try to get the value from cache
              cached_val = cache.get(cache_key)
              if cached_val is None:
                  # Call the original function and cache the result
                  cached_val = f(*args, **kwargs)
                  cache.set(cache_key, cached_val, timeout)
              return cached_val
  
          return wrapped
  
      return decorator