14
14
import json
15
15
import time
16
16
from datetime import timedelta
17
- from typing import TYPE_CHECKING , Any , List , Optional , Tuple
17
+ from typing import TYPE_CHECKING , Any , List , Optional , Tuple , Union
18
18
19
19
import litellm
20
20
from litellm ._logging import print_verbose , verbose_logger
26
26
27
27
if TYPE_CHECKING :
28
28
from opentelemetry .trace import Span as _Span
29
- from redis .asyncio import Redis
29
+ from redis .asyncio import Redis , RedisCluster
30
30
from redis .asyncio .client import Pipeline
31
+ from redis .asyncio .cluster import ClusterPipeline
31
32
32
33
pipeline = Pipeline
34
+ cluster_pipeline = ClusterPipeline
33
35
async_redis_client = Redis
36
+ async_redis_cluster_client = RedisCluster
34
37
Span = _Span
35
38
else :
36
39
pipeline = Any
40
+ cluster_pipeline = Any
37
41
async_redis_client = Any
42
+ async_redis_cluster_client = Any
38
43
Span = Any
39
44
40
45
@@ -122,7 +127,9 @@ def __init__(
122
127
else :
123
128
super ().__init__ () # defaults to 60s
124
129
125
- def init_async_client (self ):
130
+ def init_async_client (
131
+ self ,
132
+ ) -> Union [async_redis_client , async_redis_cluster_client ]:
126
133
from .._redis import get_redis_async_client
127
134
128
135
return get_redis_async_client (
@@ -345,8 +352,14 @@ async def async_set_cache(self, key, value, **kwargs):
345
352
)
346
353
347
354
async def _pipeline_helper (
348
- self , pipe : pipeline , cache_list : List [Tuple [Any , Any ]], ttl : Optional [float ]
355
+ self ,
356
+ pipe : Union [pipeline , cluster_pipeline ],
357
+ cache_list : List [Tuple [Any , Any ]],
358
+ ttl : Optional [float ],
349
359
) -> List :
360
+ """
361
+ Helper function for executing a pipeline of set operations on Redis
362
+ """
350
363
ttl = self .get_ttl (ttl = ttl )
351
364
# Iterate through each key-value pair in the cache_list and set them in the pipeline.
352
365
for cache_key , cache_value in cache_list :
@@ -359,7 +372,11 @@ async def _pipeline_helper(
359
372
_td : Optional [timedelta ] = None
360
373
if ttl is not None :
361
374
_td = timedelta (seconds = ttl )
362
- pipe .set (cache_key , json_cache_value , ex = _td )
375
+ pipe .set ( # type: ignore
376
+ name = cache_key ,
377
+ value = json_cache_value ,
378
+ ex = _td ,
379
+ )
363
380
# Execute the pipeline and return the results.
364
381
results = await pipe .execute ()
365
382
return results
@@ -373,9 +390,8 @@ async def async_set_cache_pipeline(
373
390
# don't waste a network request if there's nothing to set
374
391
if len (cache_list ) == 0 :
375
392
return
376
- from redis .asyncio import Redis
377
393
378
- _redis_client : Redis = self .init_async_client () # type: ignore
394
+ _redis_client = self .init_async_client ()
379
395
start_time = time .time ()
380
396
381
397
print_verbose (
@@ -384,7 +400,7 @@ async def async_set_cache_pipeline(
384
400
cache_value : Any = None
385
401
try :
386
402
async with _redis_client as redis_client :
387
- async with redis_client .pipeline (transaction = True ) as pipe :
403
+ async with redis_client .pipeline (transaction = False ) as pipe :
388
404
results = await self ._pipeline_helper (pipe , cache_list , ttl )
389
405
390
406
print_verbose (f"pipeline results: { results } " )
@@ -730,7 +746,8 @@ async def async_batch_get_cache(
730
746
"""
731
747
Use Redis for bulk read operations
732
748
"""
733
- _redis_client = await self .init_async_client ()
749
+ # typed as Any, redis python lib has incomplete type stubs for RedisCluster and does not include `mget`
750
+ _redis_client : Any = self .init_async_client ()
734
751
key_value_dict = {}
735
752
start_time = time .time ()
736
753
try :
@@ -822,7 +839,8 @@ def sync_ping(self) -> bool:
822
839
raise e
823
840
824
841
async def ping (self ) -> bool :
825
- _redis_client = self .init_async_client ()
842
+ # typed as Any, redis python lib has incomplete type stubs for RedisCluster and does not include `ping`
843
+ _redis_client : Any = self .init_async_client ()
826
844
start_time = time .time ()
827
845
async with _redis_client as redis_client :
828
846
print_verbose ("Pinging Async Redis Cache" )
@@ -858,7 +876,8 @@ async def ping(self) -> bool:
858
876
raise e
859
877
860
878
async def delete_cache_keys (self , keys ):
861
- _redis_client = self .init_async_client ()
879
+ # typed as Any, redis python lib has incomplete type stubs for RedisCluster and does not include `delete`
880
+ _redis_client : Any = self .init_async_client ()
862
881
# keys is a list, unpack it so it gets passed as individual elements to delete
863
882
async with _redis_client as redis_client :
864
883
await redis_client .delete (* keys )
@@ -881,7 +900,8 @@ async def disconnect(self):
881
900
await self .async_redis_conn_pool .disconnect (inuse_connections = True )
882
901
883
902
async def async_delete_cache (self , key : str ):
884
- _redis_client = self .init_async_client ()
903
+ # typed as Any, redis python lib has incomplete type stubs for RedisCluster and does not include `delete`
904
+ _redis_client : Any = self .init_async_client ()
885
905
# keys is str
886
906
async with _redis_client as redis_client :
887
907
await redis_client .delete (key )
@@ -936,7 +956,7 @@ async def async_increment_pipeline(
936
956
937
957
try :
938
958
async with _redis_client as redis_client :
939
- async with redis_client .pipeline (transaction = True ) as pipe :
959
+ async with redis_client .pipeline (transaction = False ) as pipe :
940
960
results = await self ._pipeline_increment_helper (
941
961
pipe , increment_list
942
962
)
@@ -991,7 +1011,8 @@ async def async_get_ttl(self, key: str) -> Optional[int]:
991
1011
Redis ref: https://redis.io/docs/latest/commands/ttl/
992
1012
"""
993
1013
try :
994
- _redis_client = await self .init_async_client ()
1014
+ # typed as Any, redis python lib has incomplete type stubs for RedisCluster and does not include `ttl`
1015
+ _redis_client : Any = self .init_async_client ()
995
1016
async with _redis_client as redis_client :
996
1017
ttl = await redis_client .ttl (key )
997
1018
if ttl <= - 1 : # -1 means the key does not exist, -2 key does not exist
0 commit comments