Skip to content

Commit

Permalink
Hit cache indication (#532)
Browse files Browse the repository at this point in the history
* endpoint_params

* response_hit_indication

* revert endpoint_params

* unrevert endpoint_params

* revert

* tester
change log

---------

Co-authored-by: Ido Shraga <[email protected]>
Co-authored-by: northernSage <[email protected]>
  • Loading branch information
3 people authored May 4, 2024
1 parent c1b683c commit 59cf9af
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 0 deletions.
9 changes: 9 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
Changelog
=========


Version 2.3.0
-------------

- add indication if cache is used in the response header.
- Added ``response_hit_indication`` flag to ``Cache.cached`` decorator for appending 'hit_cache' headers to responses, indicating cache hits.


Version 2.2.0
-------------

Expand All @@ -18,6 +26,7 @@ Released 2024-10-08
- Added docs and example for make_cache_key
- support Flask 3


Version 2.0.2
-------------

Expand Down
15 changes: 15 additions & 0 deletions src/flask_caching/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,7 @@ def cached(
cache_none: bool = False,
make_cache_key: Optional[Callable] = None,
source_check: Optional[bool] = None,
response_hit_indication: Optional[bool] = False,
) -> Callable:
"""Decorator. Use this to cache a function. By default the cache key
is `view/request.path`. You are able to use this decorator with any
Expand Down Expand Up @@ -351,6 +352,10 @@ def get_list():
formed with the function's source code hash in
addition to other parameters that may be included
in the formation of the key.
:param response_hit_indication: Default False.
If True, it will add to response header field 'hit_cache'
if used cache.
"""

def decorator(f):
Expand Down Expand Up @@ -406,6 +411,16 @@ def decorated_function(*args, **kwargs):
raise
logger.exception("Exception possibly due to cache backend.")
return self._call_fn(f, *args, **kwargs)
if found and self.app.debug:
logger.info(f"Cache used for key: {cache_key}")
if response_hit_indication:

def apply_caching(response):
if found:
response.headers["hit_cache"] = found
return response

self.app.after_request_funcs[None].append(apply_caching)

if not found:
rv = self._call_fn(f, *args, **kwargs)
Expand Down
14 changes: 14 additions & 0 deletions tests/test_view.py
Original file line number Diff line number Diff line change
Expand Up @@ -573,3 +573,17 @@ def view_works():
# Now make sure the time for the first and third responses are the same
# i.e. cached is used since cache will not check for source changes!
assert third_time == first_time


def test_hit_cache(app, cache):
@app.route("/")
@cache.cached(10, response_hit_indication=True)
def cached_view():
# This should override the timeout to be 2 seconds
return {"data": "data"}

tc = app.test_client()

assert tc.get("/").headers.get("hit_cache") is None
assert tc.get("/").headers.get("hit_cache") == "True"
assert tc.get("/").headers.get("hit_cache") == "True"

0 comments on commit 59cf9af

Please sign in to comment.