@@ -127,13 +127,19 @@ async def inner_wrapper(
127127 return outer_wrapper
128128
129129
130- def expires (tag : str | None = None ) -> Callable [..., Any ]:
130+ def expires (
131+ tag : str | None = None ,
132+ arg : str | None = None , # noqa: ARG001
133+ ) -> Callable [..., Any ]:
131134 """Invalidate all cached responses with the same tag.
132135
133136 Args:
134- tag (str, optional): A tag to associate with the cached response. This
135- can later be used to invalidate all cached responses with the same
136- tag, or for further fine-grained cache expiry. Defaults to None.
137+ tag (str, optional): The tag to search for keys to expire.
138+ Defaults to None.
139+ arg: (str, optional): The function arguement to filter for expiry. This
140+ would generally be the varying arguement suppplied to the route.
141+ Defaults to None. If not specified, the kwargs for the route will
142+ be used to search for the key to expire.
137143 """
138144
139145 def outer_wrapper (func : Callable [..., Any ]) -> Callable [..., Any ]:
@@ -144,14 +150,26 @@ async def inner_wrapper(
144150 ) -> Any : # noqa: ANN401
145151 """Invalidate all cached responses with the same tag."""
146152 redis_cache = FastApiRedisCache ()
147- if redis_cache .not_connected :
148- return await get_api_response_async (func , * args , ** kwargs )
149- if tag :
150- # expire all keys with the same tag. This is a test we will
151- # later only expire keys that have the search argument in the
152- # key.
153+ orig_response = await get_api_response_async (func , * args , ** kwargs )
154+
155+ if not redis_cache .redis or not redis_cache .connected or not tag :
156+ # we only want to invalidate the cache if the redis client is
157+ # connected and a tag is provided.
158+ return orig_response
159+ if kwargs :
160+ search = "" .join (
161+ [f"({ key } ={ value } )" for key , value in kwargs .items ()]
162+ )
163+ tag_keys = redis_cache .get_tagged_keys (tag )
164+ found_keys = [key for key in tag_keys if search .encode () in key ]
165+ for key in found_keys :
166+ redis_cache .redis .delete (key )
167+ redis_cache .redis .srem (tag , key )
168+ else :
169+ # will fill this later, what to do if no kwargs are provided
153170 pass
154- return await get_api_response_async (func , * args , ** kwargs )
171+
172+ return orig_response
155173
156174 return inner_wrapper
157175
0 commit comments