Skip to content

Commit 9bf1d54

Browse files
committed
log key deletion and return data as a Response()
Signed-off-by: Grant Ramsay <seapagan@gmail.com>
1 parent f8f60da commit 9bf1d54

File tree

5 files changed

+36
-17
lines changed

5 files changed

+36
-17
lines changed

.pre-commit-config.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ repos:
1212
- id: end-of-file-fixer
1313

1414
- repo: https://github.com/astral-sh/ruff-pre-commit
15-
rev: v0.4.1
15+
rev: v0.4.2
1616
hooks:
1717
- id: ruff
1818
name: "lint with ruff"
@@ -28,7 +28,7 @@ repos:
2828
args: [-d, "MD046", scan]
2929

3030
- repo: https://github.com/pre-commit/mirrors-mypy
31-
rev: "v1.9.0" # Use the sha / tag you want to point at
31+
rev: "v1.10.0" # Use the sha / tag you want to point at
3232
hooks:
3333
- id: mypy
3434
name: "Check with Mypy"

fastapi_redis_cache/cache.py

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
from fastapi import Response
1212

1313
from fastapi_redis_cache.client import FastApiRedisCache
14+
from fastapi_redis_cache.enums import RedisEvent
1415
from fastapi_redis_cache.util import (
1516
ONE_DAY_IN_SECONDS,
1617
ONE_HOUR_IN_SECONDS,
@@ -69,6 +70,7 @@ async def inner_wrapper(
6970
# if the redis client is not connected or request is not
7071
# cacheable, no caching behavior is performed.
7172
return await get_api_response_async(func, *args, **kwargs)
73+
7274
key = redis_cache.get_cache_key(tag, func, *args, **kwargs)
7375
ttl, in_cache = redis_cache.check_cache(key)
7476
if in_cache:
@@ -150,29 +152,45 @@ async def inner_wrapper(
150152
**kwargs: Any, # noqa: ANN401
151153
) -> Any: # noqa: ANN401
152154
"""Invalidate all cached responses with the same tag."""
153-
_headers = kwargs.get("request", None).headers
155+
response = kwargs.get("response", None)
156+
create_response_directly = not response
157+
158+
if create_response_directly:
159+
response = Response()
160+
if "content-length" in response.headers:
161+
del response.headers["content-length"]
154162

155163
redis_cache = FastApiRedisCache()
156164
orig_response = await get_api_response_async(func, *args, **kwargs)
157165

158-
if not redis_cache.redis or not redis_cache.connected or not tag:
159-
# we only want to invalidate the cache if the redis client is
160-
# connected and a tag is provided.
161-
return orig_response
162-
if kwargs:
166+
ignore_args = redis_cache.ignore_arg_types
167+
168+
if all([redis_cache.redis, redis_cache.connected, tag, kwargs]):
169+
# remove any args that should not be used to generate the cache
170+
# key.
171+
filtered_kwargs = kwargs.copy()
172+
for arg in ignore_args:
173+
filtered_kwargs.pop(arg, None)
163174
search = "".join(
164-
[f"({key}={value})" for key, value in kwargs.items()]
175+
[
176+
f"({key}={value})"
177+
for key, value in filtered_kwargs.items()
178+
]
165179
)
166180
tag_keys = redis_cache.get_tagged_keys(tag)
167181
found_keys = [key for key in tag_keys if search.encode() in key]
168182
for key in found_keys:
183+
redis_cache.log(
184+
RedisEvent.KEY_DELETED_FROM_CACHE, key=key.decode()
185+
)
169186
redis_cache.redis.delete(key)
170187
redis_cache.redis.srem(tag, key)
171-
else:
172-
# will fill this later, what to do if no kwargs are provided
173-
pass
174188

175-
return orig_response
189+
return Response(
190+
content=serialize_json(orig_response),
191+
media_type=JSON_MEDIA_TYPE,
192+
headers=response.headers,
193+
)
176194

177195
return inner_wrapper
178196

fastapi_redis_cache/client.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,9 @@ def add_to_cache(self, key: str, value: Any, expire: int) -> bool:
205205
message = f"Object of type {type(value)} is not JSON-serializable"
206206
self.log(RedisEvent.FAILED_TO_CACHE_KEY, msg=message, key=key)
207207
return False
208+
208209
cached = self.redis.set(name=key, value=response_data, ex=expire)
210+
209211
if not cached:
210212
self.log(RedisEvent.FAILED_TO_CACHE_KEY, key=key, value=value)
211213
return False

fastapi_redis_cache/enums.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,4 @@ class RedisEvent(IntEnum):
2121
KEY_ADDED_TO_CACHE = 4
2222
KEY_FOUND_IN_CACHE = 5
2323
FAILED_TO_CACHE_KEY = 6
24+
KEY_DELETED_FROM_CACHE = 7

tests/live_test.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ def cache_invalid_type(request: Request, response: Response) -> logging.Logger:
9999

100100
@app.get("/cache_with_args/{user}")
101101
@cache_one_hour(tag="user_tag")
102-
def cache_with_args(user: int, request: Request) -> dict[str, Union[bool, str]]:
102+
def cache_with_args(user: int) -> dict[str, Union[bool, str]]:
103103
"""Have a varying cache key based on the user argument."""
104104
return {
105105
"success": True,
@@ -109,9 +109,7 @@ def cache_with_args(user: int, request: Request) -> dict[str, Union[bool, str]]:
109109

110110
@app.put("/cache_with_args/{user}")
111111
@expires(tag="user_tag")
112-
def put_cache_with_args(
113-
user: int, request: Request
114-
) -> dict[str, Union[bool, str]]:
112+
def put_cache_with_args(user: int) -> dict[str, Union[bool, str]]:
115113
"""Put request to change data for a specific user."""
116114
return {
117115
"success": True,

0 commit comments

Comments
 (0)