def METHOD_NAME(ttl: int | None = 3600, user: str | bool | None = None) -> Callable:
	"""Decorator to cache method calls and its return values in Redis
	args:
	        ttl: time to expiry in seconds, defaults to 1 hour
	        user: `true` should cache be specific to session user.
	"""
	def wrapper(func: Callable = None) -> Callable:
		func_key = f"{func.__module__}.{func.__qualname__}"
		def clear_cache():
			frappe.cache.delete_keys(func_key)
		func.clear_cache = clear_cache
		func.ttl = ttl if not callable(ttl) else 3600
		@wraps(func)
		def redis_cache_wrapper(*args, **kwargs):
			func_call_key = func_key + "::" + str(__generate_request_cache_key(args, kwargs))
			if frappe.cache.exists(func_call_key):
				return frappe.cache.get_value(func_call_key, user=user)
			else:
				val = func(*args, **kwargs)
				ttl = getattr(func, "ttl", 3600)
				frappe.cache.set_value(func_call_key, val, expires_in_sec=ttl, user=user)
				return val
		return redis_cache_wrapper
	if callable(ttl):
		return wrapper(ttl)
	return wrapper