Exemple #1
0
    def decorator(f):
        @wraps(f)
        def wrapper(*args, **kwargs):
            # check if the user can access the resource
            check_perms(*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":
                return f(*args, **kwargs)

            response = None
            if cache:
                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(f, *key_args, **key_kwargs)
                    response = cache.get(cache_key)
                except Exception:  # pylint: disable=broad-except
                    if app.debug:
                        raise
                    logging.exception("Exception possibly due to cache backend.")

            # 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
                response.cache_control.public = True
                response.last_modified = datetime.utcnow()
                expiration = max_age if max_age != 0 else FAR_FUTURE
                response.expires = response.last_modified + timedelta(
                    seconds=expiration
                )
                response.add_etag()

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

            return response.make_conditional(request)

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

        return wrapper
Exemple #2
0
    def decorator(f):
        @wraps(f)
        def wrapper(*args, **kwargs):
            # check if the user can access the resource
            check_perms(*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':
                return f(*args, **kwargs)

            response = None
            if cache:
                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(f, *key_args, **key_kwargs)
                    response = cache.get(cache_key)
                except Exception:  # pylint: disable=broad-except
                    if app.debug:
                        raise
                    logging.exception('Exception possibly due to cache backend.')

            # 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
                response.cache_control.public = True
                response.last_modified = datetime.utcnow()
                expiration = max_age if max_age != 0 else FAR_FUTURE
                response.expires = \
                    response.last_modified + timedelta(seconds=expiration)
                response.add_etag()

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

            return response.make_conditional(request)

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

        return wrapper
    def decorator(f: Callable[..., Any]) -> Callable[..., Any]:
        @wraps(f)
        def wrapper(*args: Any, **kwargs: Any) -> ETagResponseMixin:
            # check if the user can access the resource
            check_perms(*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
            last_modified = get_last_modified and get_last_modified(*args, **kwargs)

            if cache:
                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.")

                # if cache is stale?
                if (
                    response
                    and last_modified
                    and response.last_modified
                    and response.last_modified < last_modified
                ):
                    response = None

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

                # set expiration headers:
                #   Last-Modified, Expires, Cache-Control, ETag
                response.last_modified = last_modified or datetime.utcnow()
                expiration = max_age if max_age != 0 else FAR_FUTURE
                response.expires = response.last_modified + timedelta(
                    seconds=expiration
                )

                # when needed, instruct the browser to always revalidate cache
                if must_revalidate:
                    # `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.add_etag()

                # if we have a cache, store the response from the request
                if cache:
                    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)

        if cache:
            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
    def decorator(f: Callable[..., Any]) -> Callable[..., Any]:
        @wraps(f)
        def wrapper(*args: Any, **kwargs: Any) -> ETagResponseMixin:
            # check if the user can access the resource
            check_perms(*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
            if cache:
                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.")

            # if cache is stale?
            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()
                ):
                    response = None
            else:
                # if caller didn't provide content's last_modified time, assume
                # its cache won't be stale.
                content_changed_time = datetime.utcnow()

            # 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
                response.cache_control.public = True
                response.last_modified = content_changed_time
                expiration = max_age if max_age != 0 else FAR_FUTURE
                response.expires = response.last_modified + timedelta(
                    seconds=expiration
                )
                response.add_etag()

                # if we have a cache, store the response from the request
                if cache:
                    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)

        if cache:
            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