def decorator()

in superset/utils/cache.py [0:0]


    def decorator(f: Callable[..., Any]) -> Callable[..., Any]:  # noqa: C901
        @wraps(f)
        def wrapper(*args: Any, **kwargs: Any) -> Response:  # noqa: C901
            # Check if the user can access the resource
            if raise_for_access:
                try:
                    raise_for_access(*args, **kwargs)
                except Exception:  # pylint: disable=broad-except
                    # If there's no access, bypass the cache and let the function
                    # handle the response.
                    return f(*args, **kwargs)

            # for POST requests we can't set cache headers, use the response
            # cache nor use conditional requests; this will still use the
            # dataframe cache in `superset/viz.py`, though.
            if request.method == "POST" or (skip and skip(*args, **kwargs)):
                return f(*args, **kwargs)

            response = None
            try:
                # build the cache key from the function arguments and any
                # other additional GET arguments (like `form_data`, eg).
                key_args = list(args)
                key_kwargs = kwargs.copy()
                key_kwargs.update(request.args)
                cache_key = wrapper.make_cache_key(  # type: ignore
                    f, *key_args, **key_kwargs
                )
                response = cache.get(cache_key)
            except Exception:  # pylint: disable=broad-except
                if app.debug:
                    raise
                logger.exception("Exception possibly due to cache backend.")

            # Check if the cache is stale. Default the content_changed_time to now
            # if we don't know when it was last modified.
            content_changed_time = datetime.utcnow()
            if get_last_modified:
                content_changed_time = get_last_modified(*args, **kwargs)
                if (
                    response
                    and response.last_modified
                    and response.last_modified.timestamp()
                    < content_changed_time.timestamp()
                ):
                    # Bypass the cache if the response is stale
                    response = None

            # if no response was cached, compute it using the wrapped function
            if response is None:
                response = f(*args, **kwargs)

                # add headers for caching: Last Modified, Expires and ETag
                # always revalidate the cache if we're checking permissions or
                # if the response was modified
                if get_last_modified or raise_for_access:
                    # `Cache-Control: no-cache` asks the browser to always store
                    # the cache, but also must validate it with the server.
                    response.cache_control.no_cache = True
                else:
                    # `Cache-Control: Public` asks the browser to always store
                    # the cache.
                    response.cache_control.public = True

                response.last_modified = content_changed_time
                expiration = max_age or ONE_YEAR  # max_age=0 also means far future
                response.expires = response.last_modified + timedelta(
                    seconds=expiration
                )
                response.add_etag()

                # if we have a cache, store the response from the request
                try:
                    cache.set(cache_key, response, timeout=max_age)
                except Exception:  # pylint: disable=broad-except
                    if app.debug:
                        raise
                    logger.exception("Exception possibly due to cache backend.")

            return response.make_conditional(request)

        wrapper.uncached = f  # type: ignore
        wrapper.cache_timeout = max_age  # type: ignore
        wrapper.make_cache_key = cache._memoize_make_cache_key(  # type: ignore # pylint: disable=protected-access
            make_name=None, timeout=max_age
        )

        return wrapper