1- from typing import Callable , Union , List , Dict , Any
1+ from typing import Callable , Union , Tuple , List , Dict , Any
22import functools
33import json
44import re
77from fastapi .encoders import jsonable_encoder
88from redis .asyncio import Redis , ConnectionPool
99
10- from app .core .exceptions .cache_exceptions import CacheIdentificationInferenceError , InvalidRequestError
10+ from app .core .exceptions .cache_exceptions import CacheIdentificationInferenceError , InvalidRequestError , MissingClientError
1111
1212pool : ConnectionPool | None = None
1313client : Redis | None = None
1414
15- def _infer_resource_id (kwargs : Dict [str , Any ], resource_id_type : Union [type , str ]) -> Union [None , int , str ]:
15+ def _infer_resource_id (kwargs : Dict [str , Any ], resource_id_type : Union [type , Tuple [ type , ...] ]) -> Union [None , int , str ]:
1616 """
1717 Infer the resource ID from a dictionary of keyword arguments.
1818
1919 Parameters
2020 ----------
2121 kwargs: Dict[str, Any]
2222 A dictionary of keyword arguments.
23- resource_id_type: Union[type, str]
24- The expected type of the resource ID, which can be an integer (int) or a string (str).
23+ resource_id_type: Union[type, Tuple[type, ...]]
24+ The expected type of the resource ID, which can be integer (int) or a string (str).
2525
2626 Returns
2727 -------
@@ -30,8 +30,8 @@ def _infer_resource_id(kwargs: Dict[str, Any], resource_id_type: Union[type, str
3030
3131 Note
3232 ----
33- - When `resource_id_type` is ' int' , the function looks for an argument with the key 'id'.
34- - When `resource_id_type` is ' str' , it attempts to infer the resource ID as a string.
33+ - When `resource_id_type` is ` int` , the function looks for an argument with the key 'id'.
34+ - When `resource_id_type` is ` str` , it attempts to infer the resource ID as a string.
3535 """
3636 resource_id = None
3737 for arg_name , arg_value in kwargs .items ():
@@ -177,7 +177,10 @@ async def _delete_keys_by_pattern(pattern: str):
177177 - Be cautious with patterns that could match a large number of keys, as deleting
178178 many keys simultaneously may impact the performance of the Redis server.
179179 """
180- cursor = "0"
180+ if client is None :
181+ raise MissingClientError
182+
183+ cursor = - 1
181184 while cursor != 0 :
182185 cursor , keys = await client .scan (cursor , match = pattern , count = 100 )
183186 if keys :
@@ -188,7 +191,7 @@ def cache(
188191 key_prefix : str ,
189192 resource_id_name : Any = None ,
190193 expiration : int = 3600 ,
191- resource_id_type : Union [type , List [type ]] = int ,
194+ resource_id_type : Union [type , Tuple [type , ... ]] = int ,
192195 to_invalidate_extra : Dict [str , Any ] | None = None ,
193196 pattern_to_invalidate_extra : List [str ] | None = None
194197) -> Callable :
@@ -207,8 +210,8 @@ def cache(
207210 otherwise, the resource ID is inferred from the function's arguments.
208211 expiration: int, optional
209212 The expiration time for the cached data in seconds. Defaults to 3600 seconds (1 hour).
210- resource_id_type: Union[type, List [type]], optional
211- The expected type of the resource ID. This can be a single type (e.g., int) or a list of types (e.g., [ int, str] ).
213+ resource_id_type: Union[type, Tuple [type, ... ]], default int
214+ The expected type of the resource ID. This can be a single type (e.g., int) or a tuple of types (e.g., ( int, str) ).
212215 Defaults to int. This is used only if resource_id_name is not provided.
213216 to_invalidate_extra: Dict[str, Any] | None, optional
214217 A dictionary where keys are cache key prefixes and values are templates for cache key suffixes.
@@ -286,6 +289,9 @@ async def update_item(request: Request, item_id: int, data: dict, user_id: int):
286289 def wrapper (func : Callable ) -> Callable :
287290 @functools .wraps (func )
288291 async def inner (request : Request , * args , ** kwargs ) -> Response :
292+ if client is None :
293+ raise MissingClientError
294+
289295 if resource_id_name :
290296 resource_id = kwargs [resource_id_name ]
291297 else :
0 commit comments