
    h                     *   d Z ddlZddlZddlZddlZddlZddlmZ ddlm	Z	m
Z
mZmZmZmZmZ ddlZddlmZmZ ddlmZ ddlmZ ddlmZ d	d
lmZ e	r*ddlmZ ddlm Z m!Z! ddl"m#Z# ddl$m%Z% e#Z&e%Z'e Z(e!Z)eee
f   Zn
e
Z&e
Z'e
Z(e
Z)e
Z G d de      Z*y)z
Redis Cache implementation

Has 4 primary methods:
    - set_cache
    - get_cache
    - async_set_cache
    - async_get_cache
    N)	timedelta)TYPE_CHECKINGAnyListOptionalTupleUnioncast)print_verboseverbose_logger)!_get_parent_otel_span_from_kwargs)RedisPipelineIncrementOperation)ServiceTypes   )	BaseCache)Span)RedisRedisCluster)Pipeline)ClusterPipelinec                       e Zd Z	 	 	 	 	 	 	 d<dee   dee   dee   dee   f fdZde	e
ef   fdZd	edefd
Zd Z	 d=dedee   defdZd>dededefdZdedefdZd Zde	eef   deeeef      dee   defdZ	 d=deeeef      dee   fdZde
d	ededee   ddf
dZdedee   fdZd Z	 	 d?dedee   dee   defdZd Zd efd!Z d=dee   fd"Z!d#ee   dee   fd$Z"d#ee   dee   fd%Z#	 d=d&e	ee   eee      f   dee   de$fd'Z%	 d=dee   fd(Z&	 d=d&e	ee   eee      f   dee   de$fd)Z'de(fd*Z)de(fd+Z*d, Z+defd-Z,d. Z-d/ Z.d0 Z/d1 Z0d	efd2Z1d3 Z2ded4ee3   deee      fd5Z4d4ee3   deee      fd6Z5d	edee   fd7Z6	 d=d	ed8ee   dee   defd9Z7ded	ededee8   fd:Z9	 	 d?d	edee   dee   de	eee   f   fd;Z: xZ;S )@
RedisCacheNredis_flush_size	namespacestartup_nodessocket_timeoutc                    ddl m}	 ddlm}
m} i }|||d<   |||d<   |||d<   |||d<   |||d	<   |j                  d
d       &t        |d
   |	      r|j                  d
      | _        n |	       | _        |j                  |        |
di || _
        d | _        || _         |di || _        || _        g | _        |d| _        n|| _        d| _        	 t%        j&                  | j                        s"| j                  j)                         d   | _        	 t-        j.                         j1                  | j3                               }	 t?        | j                  d      r| j                  j3                          t@        jB                  (tD        |   tI        t@        jB                               y tD        |           y # t*        $ r Y w xY w# t*        $ rg}dt5        |      v rt7        j8                  d       n:t7        j:                  dj=                  t5        |            dt5        |      i       Y d }~d }~ww xY w# t*        $ r,}t7        j:                  ddt5        |      i       Y d }~d }~ww xY w)Nr   )ServiceLogging   )get_redis_clientget_redis_connection_poolhostportpasswordr   r   service_logger_objd   Unknownredis_versionzno running event loopz1Ignoring async redis ping. No running event loop.z+Error connecting to Async Redis client - {}error)extrapingz%Error connecting to Sync Redis client)default_ttl )%litellm._service_loggerr   _redisr    r!   get
isinstancepopr%   updateredis_clientredis_async_clientredis_kwargsasync_redis_conn_poolr   redis_batch_writing_bufferr   r(   inspectiscoroutinefunctioninfo	Exceptionasyncioget_running_loopcreate_taskr+   strr   debugr)   formathasattrlitellmdefault_redis_ttlsuper__init__int)selfr"   r#   r$   r   r   r   r   kwargsr   r    r!   r6   _e	__class__s                  W/var/www/Befach/backend/env/lib/python3.12/site-packages/litellm/caching/redis_cache.pyrG   zRedisCache.__init__1   sr    	;H#'L #'L '/L$$,9L)%-;L)* ::*D1=*'(.C
 '-jj1E&FD#&4&6D#F#,<|<  	 )%>%N%N" #02'#),D!$4D!&	..t/@/@A%)%6%6%;%;%=o%N"
	((*66tyy{CA	t((&1!!&&( $$0GW-F-F)GHG=  		  		&#a&0$$G $$AHHQP"CF+		  	  7Q?P 	sD   AG 1G 0I 	GG	IAH>>I	I;"I66I;returnc                 8   ddl m} ddlm}m} |j                  d      }|t        t        t        t        f   |      }nR |d	i | j                  | _         |d	d| j                  i| j                  }|j                  d| j                         || _        |S )
Nr   )in_memory_llm_clients_cacher   )get_redis_async_clientr!   zasync-redis-clientkeyconnection_pool)rT   valuer-   )rD   rQ   r/   rR   r!   	get_cacher
   r	   async_redis_clientasync_redis_cluster_clientr6   r7   	set_cacher5   )rI   rQ   rR   r!   cached_clientr5   s         rN   init_async_clientzRedisCache.init_async_client   s     	8N3==BV=W$!%(*DDE}"
 *C)WTEVEV)WD&!7 " $ : :">B>O>O" (11(0G0G 2  #5!!    rT   c                 x    | j                   -|j                  | j                         s| j                   dz   |z   }|S )zD
        Make sure each key starts with the given namespace
        :)r   
startswithrI   rT   s     rN   check_and_fix_namespacez"RedisCache.check_and_fix_namespace   s5     >>%cnnT^^.L..3&,C
r]   c           
          | j                   d
i |}t        d| d| d| d| j                          | j                  |      }	 t	        j                         }| j
                  j                  |t        |      |       t	        j                         }||z
  }| j                  j                  t        j                  |d||       y # t        $ r!}t        d	t        |              Y d }~y d }~ww xY w)NzSet Redis Cache: key: 
Value 
ttl=, redis_version=rS   namerV   exrZ   serviceduration	call_type
start_timeend_timez<litellm.caching.caching: set() - Got exception from REDIS : r-   )get_ttlr   r(   rb   timer4   setr@   r%   service_success_hookr   REDISr<   )	rI   rT   rV   rJ   ttlrn   ro   	_durationrL   s	            rN   rZ   zRedisCache.set_cache   s    dll$V$$SE%seCSTXTfTfSgh	
 **s*3	J!!s#e*!Eyy{H :-I##88$**"%%! 9   	NsSTvhW 	s   BC
 
	C4C//C4rV   ru   c                    | j                   }t        j                         }| j                  |      }	 t        j                         }|j                  ||      }t        j                         }	|	|z
  }
| j                  j                  t        j                  |
d||	       |t        j                         }|j                  |      }t        j                         }	|	|z
  }
| j                  j                  t        j                  |
d||	       |dk(  rmt        j                         }|j                  ||       t        j                         }	|	|z
  }
| j                  j                  t        j                  |
d||	       |S # t        $ r@}t        j                         }	|	|z
  }
t        j                  dt        |      |       |d }~ww xY w)	Nru   rh   amountincrement_cacherj   increment_cache_ttlincrement_cache_expirezXLiteLLM Redis Caching: increment_cache() - Got exception from REDIS %s, Writing value=%s)r4   rq   rp   incrr%   rs   r   rt   ru   expirer<   r   r)   r@   )rI   rT   rV   ru   rJ   _redis_clientrn   set_ttlresultro   rv   current_ttlrL   s                rN   r{   zRedisCache.increment_cache   s    ))YY[
,,3,'1	J',,#e,DFyy{H :-I##88$**"+%! 9  "!YY[
+//499;$z1	''<<(..&3)% =  "$!%J!((g6#yy{H (: 5I++@@ , 2 2!*":#-!) A  M 		yy{H :-I  jA
 G		s   EF 	G;GGpatterncountc                   K   t        j                          }	 g }| j                         }t        |d      st        j                  d       g S |j                  |dz   |      2 3 d {   }|j                  |       t        |      |k\  s) t        j                          }||z
  }t        j                  | j                  j                  t        j                  |d||             |S 7 6 `# t        $ rb}	t        j                          }||z
  }t        j                  | j                  j                  t        j                  ||	d||             |	d }	~	ww xY ww)N	scan_iterz_Redis client does not support scan_iter, potentially using Redis Cluster. Returning empty list.*)matchr   async_scan_iterrj   )rk   rl   r)   rm   rn   ro   )rq   r\   rC   r   rA   r   appendlenr=   r?   r%   async_service_success_hookr   rt   r<   async_service_failure_hook)
rI   r   r   rn   keysr   rT   ro   rv   rL   s
             rN   r   zRedisCache.async_scan_iter   s]    YY[
*	D 224M=+6$$u 	*447S=PU4V  cC t9% yy{H :-I''BB(..&/)% C  K#V$  	 yy{H :-I''BB(..&/)% C 	 G	s`   E4C- EC- #C+'C)(C++ C- AC- (E)C++C- -	E6AEEEscriptc                 X   	 | j                         t        d      rj                  |      S t        d      r:j                  |      dt        t
           dt        t           dt        ffd}|S y# t        $ r(}t        j                  dt        |              |d}~ww xY w)	a  
        Register a Lua script with Redis asynchronously.
        Works with both standalone Redis and Redis Cluster.

        Args:
            script (str): The Lua script to register

        Returns:
            Any: A script object that can be called with keys and args
        register_scriptscript_loadr   argsrO   c                 J   K    j                   t        |       g| | S wN)evalshar   )r   r   r   
script_shas     rN   script_callablez9RedisCache.async_register_script.<locals>.script_callable?  s+     0=00SYUUPTUUs    #z Error registering Redis script: N)
r\   rC   r   r   r   r@   r   r<   r   r)   )rI   r   r   rL   r   r   s       @@rN   async_register_scriptz RedisCache.async_register_script)  s    	 224M}&78$44V<<6*66v>
VS	 Vc Vs V '& 7  	  #CCF8!LMG	s   ,A8 AA8 8	B)#B$$B)c                   K   ddl m} t        j                         }	 | j                         }| j                  |      } | j                   di |}
|j#                  dd      }t%        d	| d
| d|
        	 t'        |d      st	        d      |j)                  |t+        j,                  |      ||
       d {   }t%        d| d
| d|
        t        j                         }||z
  }	t        j                  | j                  j/                  t        j                  |	d||t        |      d|i             |S # t        $ r}t        j                         }||z
  }	t        j                  | j                  j                  t        j                  |	|||t        |      d             t        j                  dt        |      |       |d }~ww xY w7 # t        $ r}t        j                         }||z
  }	t        j                  | j                  j                  t        j                  |	|d||t        |      d|i             t        j                  dt        |      |       Y d }~y d }~ww xY ww)Nr   r   async_set_cacherk   rl   r)   rn   ro   parent_otel_spanrm   RLiteLLM Redis Caching: async set() - Got exception from REDIS %s, Writing value=%srS   nxFSet ASYNC Redis Cache: key: rd   re   rr   z3Redis client cannot set cache. Attribute not found.)rh   rV   r   ri   z)Successfully Set ASYNC Redis Cache: key: rT   rk   rl   rm   rn   ro   r   event_metadatark   rl   r)   rm   rn   ro   r   r   r-   )redis.asyncior   rq   r\   r<   r=   r?   r%   r   r   rt   r   r   r)   r@   rb   rp   r0   r   rC   rr   jsondumpsr   )rI   rT   rV   rJ   r   rn   r   rL   ro   rv   ru   r   r   s                rN   r   zRedisCache.async_set_cacheG  s    'YY[
	#'#9#9#;M, **s*3dll$V$ZZe$4SE%seTU-	=%0 UVV(,,jj'	 -  F ;C5vVYUZ[ yy{H :-I''BB(..&/)%%Fv%N$)3< C 
 Mg  	yy{H :-I''BB(..&)%%Fv%N/ C 
   dA
 G'	:.  	yy{H :-I''BB(..&/)%%Fv%N$)3< C 	   dA 	sh   I6D= A
I69AG ;G<B G <I6=	GBGGI6G 	I3!BI.)I6.I33I6pipe
cache_listc           	      8  K   | j                  |      }|D ]d  \  }}| j                  |      }t        d| d| d|        t        j                  |      }d}|t        |      }|j                  |||       f |j                          d{   }|S 7 w)	zU
        Helper function for executing a pipeline of set operations on Redis
        rx   rS   z%Set ASYNC Redis Cache PIPELINE: key: rd   re   Nsecondsrg   )rp   rb   r   r   r   r   rr   execute)	rI   r   r   ru   	cache_keycache_valuejson_cache_value_tdresultss	            rN   _pipeline_helperzRedisCache._pipeline_helper  s      llsl#&0"I{444CI7	{(;-W]^a]bc  $zz+6'+C,HH&   '1  & 's   BBBBc                   K   t        |      dk(  ry| j                         }t        j                         }t        d| d| d| j                          d}	 |j                  d      4 d{   }| j                  |||       d{   }ddd      d{    t        d        t        j                         }	|	|z
  }
t        j                  | j                  j                  t        j                  |
d	||	t        |      
             y7 7 7 {# 1 d{  7  sw Y   xY w# t        $ r}t        j                         }	|	|z
  }
t        j                  | j                  j                  t        j                  |
|d	||	t        |                   t!        j"                  dt%        |      |       Y d}~yd}~ww xY ww)z?
        Use Redis Pipelines for bulk write operations
        r   Nz!Set Async Redis Cache: key list: re   rf   Ftransactionzpipeline results: async_set_cache_pipelinerk   rl   rm   rn   ro   r   rk   rl   r)   rm   rn   ro   r   zaLiteLLM Redis Caching: async set_cache_pipeline() - Got exception from REDIS %s, Writing value=%s)r   r\   rq   r   r(   pipeliner   r=   r?   r%   r   r   rt   r   r<   r   r   r)   r@   )rI   r   ru   rJ   r   rn   r   r   r   ro   rv   rL   s               rN   r   z#RedisCache.async_set_cache_pipeline  s     z?a..0YY[
/
|6#FVW[WiWiVjk	
  (	$--%-@ M MD $ 5 5dJ LLM M .wi89 yy{H :-I''BB(..&8)%%Fv%N C 	 %MLM M M M&  	yy{H :-I''BB(..&8)%%Fv%N C 
   sA !	s   AGD+ -D.D+ 1DD	DD+ DA6D+ GD+ DD+ D(DD($D+ +	G4BF>9G>GGr4   c                    K   | j                  |      }	  |j                  |g|  d{    |'t        |      }|j                  ||       d{    yy7 .7 # t        $ r  w xY ww)z@Helper function for async_set_cache_sadd. Separated for testing.rx   Nr   )rp   saddr   r   r<   )rI   r4   rT   rV   ru   r   s         rN   _set_cache_sadd_helperz!RedisCache._set_cache_sadd_helper  s~      llsl#	#,##C0%000,"))#s333  1 4 		s>   A-A A'A AA A-A A A**A-c                 F  K   ddl m} t        j                         }	 | j                         }| j                  |      }t!        d| d| d	|        	 | j#                  ||||
       d {    t!        d| d| d	|        t        j                         }	|	|z
  }
t        j                  | j                  j%                  t        j                  |
d||	t        |                   y # t        $ r}t        j                         }	|	|z
  }
t        j                  | j                  j                  t        j                  |
|||	t        |      d             t        j                  dt        |      |       |d }~ww xY w7 # t        $ r}t        j                         }	|	|z
  }
t        j                  | j                  j                  t        j                  |
|d||	t        |                   t        j                  dt        |      |       Y d }~y d }~ww xY ww)Nr   r   async_set_cache_saddr   r   rS   r   rd   re   )r4   rT   rV   ru   z.Successfully Set ASYNC Redis Cache SADD: key: r   r   z]LiteLLM Redis Caching: async set_cache_sadd() - Got exception from REDIS %s, Writing value=%s)r   r   rq   r\   r<   r=   r?   r%   r   r   rt   r   r   r)   r@   rb   r   r   r   )rI   rT   rV   ru   rJ   r   rn   r   rL   ro   rv   s              rN   r   zRedisCache.async_set_cache_sadd   s-     	(YY[
	#'#9#9#;M. **s*34SE%seTU&	--*5c .    @XeWTZ[^Z_` yy{H :-I''BB(..&4)%%Fv%N C 	C  	yy{H :-I''BB(..&)%%Fv%N4 C 
   dA
 G)	2$  	yy{H :-I''BB(..&4)%%Fv%N C 
   oA 	sf   H!C+ &H!F -F.A<F *H!+	F 4BE;;F  H!F 	HBHH!HH!c                 &  K   t        dt        | j                                | j                  |      }| j                  j	                  ||f       t        | j                        | j
                  k\  r| j                          d {    y y 7 w)Nz-in batch cache writing for redis buffer size=rS   )r   r   r8   rb   r   r   flush_cache_buffer)rI   rT   rV   rJ   s       rN   batch_cache_writezRedisCache.batch_cache_writeH  s     ;C@_@_<`;ab	
 **s*3''..U|<t../43H3HH))+++ I+s   BBB	Br   c                 6  K   ddl m} | j                         }t        j                         }| j	                  |      }| j                  |      }	 |j                  ||       d {   }	|8|j                  |       d {   }
|
dk(  r|j                  ||       d {    t        j                         }||z
  }t        j                  | j                  j                  t        j                  |d|||             |	S 7 7 7 e# t        $ r}t        j                         }||z
  }t        j                  | j                  j!                  t        j                  ||d|||	             t#        j$                  d
t'        |      |       |d }~ww xY ww)Nr   r   rx   rS   ry   r}   async_incrementr   r   z^LiteLLM Redis Caching: async async_increment() - Got exception from REDIS %s, Writing value=%s)r   r   r\   rq   rp   rb   incrbyfloatru   r   r=   r?   r%   r   r   rt   r<   r   r   r)   r@   )rI   rT   rV   ru   r   r   r   rn   	_used_ttlr   r   ro   rv   rL   s                 rN   r   zRedisCache.async_incrementQ  s     	(#557YY[
LLSL)	**s*3,	(44#e4LLF$$1$5$5c$::"$'..sI>>> yy{H :-I''BB(..&/)%%5 C 	 M- M ; ?"  	yy{H :-I''BB(..&/)%%5 C 
   pA
 G)	sb   AFD
 (D)D
 DD
 "D#A D
 FD
 D
 D
 
	FA>FFFc                    K   t        dt        | j                                | j                  | j                         d {    g | _        y 7 w)Nz,flushing to redis....reached size of buffer )r   r   r8   r   rI   s    rN   r   zRedisCache.flush_cache_buffer  sN     :3t?^?^;_:`a	
 ++D,K,KLLL*,' 	Ms   A AAAcached_responsec                     ||S |j                  d      }	 t        j                  |      }|S # t        $ r t	        j
                  |      }Y |S w xY w)z[
        Common 'get_cache_logic' across sync + async redis client implementations
        utf-8)decoder   loadsr<   astliteral_eval)rI   r   s     rN   _get_cache_logiczRedisCache._get_cache_logic  sh     """)009	@"jjO
   	@!..?O	@s   . AAc                    	 | j                  |      }t        d|        t        j                         }| j                  j	                  |      }t        j                         }||z
  }| j
                  j                  t        j                  |d|||       t        d| d|        | j                  |      S # t        $ r }t        j                  d|       Y d }~y d }~ww xY w)	NrS   zGet Redis Cache: key: rW   r   zGot Redis Cache: key: , cached_response r   z;litellm.caching.caching: get() - Got exception from REDIS: )rb   r   rq   r4   r0   r%   rs   r   rt   r   r<   r   r)   )	rI   rT   r   rJ   rn   r   ro   rv   rL   s	            rN   rW   zRedisCache.get_cache  s    	..3.7C23%89J"//33C8Oyy{H :-I##88$**"%%!!1 9  (-??PQ (((II 	  Mq 	s   B9B< <	C%C  C%r   c                 :    | j                   j                  |      S )
        Wrapper to call `mget` on the redis client

        We use a wrapper so RedisCluster can override this method
        r   )r4   mget)rI   r   s     rN   _run_redis_mget_operationz$RedisCache._run_redis_mget_operation  s       %%4%00r]   c                 b   K   | j                         }|j                  |       d{   S 7 w)r   r   N)r\   r   )rI   r   rX   s      rN   _async_run_redis_mget_operationz*RedisCache._async_run_redis_mget_operation  s1      "335',,$,7777s   &/-/key_listc                    i }|D cg c]  }||	 }}	 g }|D ])  }| j                  |xs d      }|j                  |       + t        j                         }| j                  |      }	t        j                         }
|
|z
  }| j                  j                  t        j                  |d||
|       t        t        ||	            }i }|j                         D ]<  \  }}t        |t              r|j                  d      }| j                  |      }|||<   > |S c c}w # t        $ r-}t!        j"                  dt%        |              |cY d}~S d}~ww xY w)	a  
        Use Redis for bulk read operations

        Args:
            key_list: List of keys to get from Redis
            parent_otel_span: Optional parent OpenTelemetry span

        Returns:
            dict: A dictionary mapping keys to their cached values
        N rS   r   batch_get_cacher   r   z$Error occurred in batch get cache - )rb   r   rq   r   r%   rs   r   rt   dictzipitemsr1   bytesr   r   r<   r   r)   r@   )rI   r   r   key_value_dictrT   	_key_list_keysr   rn   r   ro   rv   decoded_resultskvrL   s                   rN   r   zRedisCache.batch_get_cache  s_    $,@SS@	@ 	"E&	 88Y_"8M	Y' ' J :::FGyy{H :-I##88$**"+%!!1 9  "#i"9:N O&,,.1a')A))!,%&"	 / #"? A@  	"  #GAx!PQ!!	"s(   DDDD! !	E*"EEEc                   K   ddl m} | j                         }| j                  |      }t	        j                         }	 t        d|        |j                  |       d {   }t        d| d|        | j                  |      }t	        j                         }	|	|z
  }
t        j                  | j                  j                  t        j                  |
d||	|d	|i
             |S 7 # t        $ r}t	        j                         }	|	|z
  }
t        j                  | j                  j                  t        j                  |
|d||	|d	|i             t        dt!        |              Y d }~y d }~ww xY ww)Nr   r   rS   zGet Async Redis Cache: key: zGot Async Redis Cache: key: r   r   async_get_cacherT   r   r   zAlitellm.caching.caching: async get() - Got exception from REDIS: )r   r   r\   rb   rq   r   r0   r   r=   r?   r%   r   r   rt   r<   r   r@   )rI   rT   r   rJ   r   r   rn   r   responsero   rv   rL   s               rN   r   zRedisCache.async_get_cache  s     	(#557**s*3YY[
'	8>?$1$5$5c$::O.se3EoEVW ,,_,MHyy{H :-I''BB(..&/)%%5$)3< C 
 O' ;(  	yy{H :-I''BB(..&/)%%5$)3< C 	 STWXYTZS[\ 	sC   =E8 "C, "C*#BC, )E8*C, ,	E55A6E0+E80E55E8c                   K   i }t        j                          }|D cg c]  }||	 }}	 g }|D ]%  }| j                  |      }|j                  |       ' | j                  |       d{   }	t        j                          }
|
|z
  }t	        j
                  | j                  j                  t        j                  |d||
|             t        t        ||	            }i }|j                         D ]<  \  }}t        |t              r|j                  d      }| j!                  |      }|||<   > |S c c}w 7 # t"        $ r}t        j                          }
|
|z
  }t	        j
                  | j                  j%                  t        j                  ||d||
|             t'        j(                  dt+        |              |cY d}~S d}~ww xY ww)	a[  
        Use Redis for bulk read operations

        Args:
            key_list: List of keys to get from Redis
            parent_otel_span: Optional parent OpenTelemetry span

        Returns:
            dict: A dictionary mapping keys to their cached values

        `.mget` does not support None keys. This will filter out None keys.
        NrS   r   async_batch_get_cacher   r   r   z*Error occurred in async batch get cache - )rq   rb   r   r   r=   r?   r%   r   r   rt   r   r   r   r1   r   r   r   r<   r   r   r)   r@   )rI   r   r   r   rn   rT   r   r   r   r   ro   rv   r   r   r   rL   s                   rN   r   z RedisCache.async_batch_get_cache4  s    $ YY[
$,@SS@	@0	"E&	 88Y8G	Y' ' !@@e@LLGyy{H :-I''BB(..&5)%%5 C 	 "#i"9:N O&,,.1a')A))!,%&"	 / #"A A M6  	"yy{H :-I''BB(..&5)%%5 C 
   #McRSfX!VW!!!	"sX   GD5D5GAD< -D:.CD< 4G:D< <	GA>G	GG	GGc                    t        d       t        j                         }	 | j                  j                         }t        d|        t        j                         }||z
  }| j                  j                  t        j                  |d||       |S # t        $ rn}t        j                         }||z
  }| j                  j                  t        j                  ||d       t        j                  dt        |              |d}~ww xY w)zD
        Tests if the sync redis client is correctly setup.
        zPinging Sync Redis CachezRedis Cache PING: 	sync_pingrj   rk   rl   r)   rm   7LiteLLM Redis Cache PING: - Got exception from REDIS : N)r   rq   r4   r+   r%   rs   r   rt   r<   service_failure_hookr   r)   r@   )rI   rn   r   ro   rv   rL   s         rN   r   zRedisCache.sync_ping{  s    	01YY[
	!..335H.xj9:yy{H :-I##88$**"%%! 9  O 	 yy{H :-I##88$**"%	 9    I#a&R G	s   A0B 	D	A)DD	c           	      l  K   | j                         }t        j                         }t        d       	 |j                          d {   }t        j                         }||z
  }t	        j
                  | j                  j                  t        j                  |d             |S 7 ^# t        $ r}t        j                         }||z
  }t	        j
                  | j                  j                  t        j                  ||d             t        j                  dt        |              |d }~ww xY ww)NzPinging Async Redis Cache
async_pingrk   rl   rm   r   r   )r\   rq   r   r+   r=   r?   r%   r   r   rt   r<   r   r   r)   r@   )rI   r   rn   r   ro   rv   rL   s          rN   r+   zRedisCache.ping  s    !335YY[
12	*//11Hyy{H :-I''BB(..&* C  O 2  	 yy{H :-I''BB(..&*	 C    I#a&R G!	s<   0D4B' B%AB' $D4%B' '	D10A<D,,D11D4c                 ^   K   | j                         } |j                  |  d {    y 7 wr   r\   delete)rI   r   r   s      rN   delete_cache_keyszRedisCache.delete_cache_keys  s*     !335"m""D)))s   #-+-c                 :    | j                   j                         }|S r   )r4   client_list)rI   r   s     rN   r   zRedisCache.client_list  s     --99;r]   c                 :    | j                   j                         }|S r   )r4   r;   )rI   r;   s     rN   r;   zRedisCache.info  s      %%'r]   c                 8    | j                   j                          y r   r4   flushallr   s    rN   flush_cachezRedisCache.flush_cache      ""$r]   c                 8    | j                   j                          y r   r   r   s    rN   r  zRedisCache.flushall  r  r]   c                 X   K   | j                   j                  d       d {    y 7 w)NT)inuse_connections)r7   
disconnectr   s    rN   r  zRedisCache.disconnect  s#     ((33d3KKKs    *(*c                 `   K   | j                         }|j                  |       d {   S 7 wr   r   )rI   rT   r   s      rN   async_delete_cachezRedisCache.async_delete_cache  s+     !335"))#....s   %.,.c                 :    | j                   j                  |       y r   )r4   r   ra   s     rN   delete_cachezRedisCache.delete_cache  s      %r]   increment_listc           
        K   |D ]m  }| j                  |d         }t        d| d|d    d|d           |j                  ||d          |d   Mt        |d   	      }|j	                  ||       o |j                          d{   }t        j                  d
|        |D cg c]  }t        |t              s| c}S 7 =c c}w w)z1Helper function for pipeline increment operationsrT   rS   z+Increment ASYNC Redis Cache PIPELINE: key: rd   increment_valuere   ru   Nr   z/Increment ASYNC Redis Cache PIPELINE: results: )
rb   r   r   r   r   r   r   rA   r1   float)rI   r   r  increment_opr   r   r   rs           rN   _pipeline_increment_helperz%RedisCache._pipeline_increment_helper  s      +L44e9L4MI=i[Q]^oQpPqqw  yE  FK  yL  xM  N Y5F(GHE".U(;<Is+ + &=gYG	
 #;ajE&:;; '
 <s0   AC6CC	 C)C?CCCc                 T  K   t        |      dk(  ryddlm} | j                         }t	        j                         }t        d|        	 |j                  d      4 d{   }| j                  ||       d{   }ddd      d{    t	        j                         }||z
  }	t        j                  | j                  j                  t        j                  |	d||t        |                   S 7 7 |7 n# 1 d{  7  sw Y   ~xY w# t        $ r}
t	        j                         }||z
  }	t        j                  | j                  j!                  t        j                  |	|
d||t        |      	             t#        j$                  d
t'        |
             |
d}
~
ww xY ww)a  
        Use Redis Pipelines for bulk increment operations
        Args:
            increment_list: List of RedisPipelineIncrementOperation dicts containing:
                - key: str
                - increment_value: float
                - ttl_seconds: int
        r   Nr   z6Increment Async Redis Cache Pipeline: increment list: Fr   async_increment_pipeliner   r   zOLiteLLM Redis Caching: async increment_pipeline() - Got exception from REDIS %s)r   r   r   r\   rq   r   r   r  r=   r?   r%   r   r   rt   r   r<   r   r   r)   r@   )rI   r  rJ   r   r   rn   r   r   ro   rv   rL   s              rN   r  z#RedisCache.async_increment_pipeline  s     ~!#'#557YY[
D^DTU	
%	$--%-@ V VD $ ? ?n UUV V yy{H :-I''BB(..&8)%%Fv%N C 	 N!VUV V V V"  	yy{H :-I''BB(..&8)%%Fv%N C 
   aA G'	s   AF(D !C6"D %C<;C8<C< D C:A)D 5F(6D 8C<:D <DDD
D 	F%BF  F%%F(c                    K   	 | j                         }|j                  |       d{   }|dk  ry|S 7 # t        $ r"}t        j                  d|        Y d}~yd}~ww xY ww)a  
        Get the remaining TTL of a key in Redis

        Args:
            key (str): The key to get TTL for

        Returns:
            Optional[int]: The remaining TTL in seconds, or None if key doesn't exist

        Redis ref: https://redis.io/docs/latest/commands/ttl/
        Nr}   zRedis TTL Error: )r\   ru   r<   r   rA   )rI   rT   r   ru   rL   s        rN   async_get_ttlzRedisCache.async_get_ttl:  sj     		!%!7!7!9M%))#..CbyJ /  	  #4QC!89	s@   A%$7 5	7 A%7 A%7 	A" AA%A""A%valuesc           	      \  K   | j                         }t        j                         }	  |j                  |g|  d{   }t        j                         }||z
  }	t        j                  | j
                  j                  t        j                  |	d             |S 7 ^# t        $ r}
t        j                         }||z
  }	t        j                  | j
                  j                  t        j                  |	|
d             t        j                  dt        |
              |
d}
~
ww xY ww)aR  
        Append one or multiple values to a list stored at key

        Args:
            key: The Redis key of the list
            values: One or more values to append to the list
            parent_otel_span: Optional parent OpenTelemetry span

        Returns:
            int: The length of the list after the push operation
        Nasync_rpushr   r   z8LiteLLM Redis Cache RPUSH: - Got exception from REDIS : )r\   rq   rpushr=   r?   r%   r   r   rt   r<   r   r   r)   r@   )rI   rT   r  r   rJ   r   rn   r   ro   rv   rL   s              rN   r  zRedisCache.async_rpushQ  s    $ "335YY[
	0]00>v>>Hyy{H :-I''BB(..&+ C  O ?  	 yy{H :-I''BB(..&+	 C    J3q6(S G!	s:   %D,B BAB D,B 	D)(A<D$$D))D,c                    K   g }t        |      D ]F  }|j                  |       |j                          d {   }|D ]  }||j                  |        H |S 7 #wr   )rangelpopr   r   )rI   r   rT   r   r   rK   r   r  s           rN   *handle_lpop_count_for_older_redis_versionsz5RedisCache.handle_lpop_count_for_older_redis_versions  s]      !uAIIcN LLN*G =MM!$    +s   5AAAAc           	        K   | j                         }t        j                         }t        d| d|        	 d}| j                  dk7  r't	        | j                  j                  d      d         }|L|dk  rG|j                  d      4 d {   }| j                  |||       d {   }	d d d       d {    n|j                  ||       d {   }	t        j                         }
|
|z
  }t        j                  | j                  j                  t        j                  |d	
             t        	t               r	 |	j#                  d      S t        |	t&              r2t)        d |	D              r 	 |	D cg c]  }|j#                  d       c}S |	S 7 	7 7 # 1 d {  7  sw Y   xY w7 # t$        $ r |	cY S w xY wc c}w # t$        $ r |	cY S w xY w# t$        $ r}t        j                         }
|
|z
  }t        j                  | j                  j+                  t        j                  ||d	             t-        j.                  dt1        |              |d }~ww xY ww)NzLPOP from Redis list: key: z	, count:    r'   .r   Fr   
async_lpopr   r   c              3   <   K   | ]  }t        |t                y wr   )r1   r   ).0items     rN   	<genexpr>z(RedisCache.async_lpop.<locals>.<genexpr>  s      2,0
4'2s   r   z7LiteLLM Redis Cache LPOP: - Got exception from REDIS : )r\   rq   r   r(   rH   splitr   r  r  r=   r?   r%   r   r   rt   r1   r   r   r<   listallr   r   r)   r@   )rI   rT   r   r   rJ   r   rn   major_versionr   r   ro   rv   r%  rL   s                 rN   r"  zRedisCache.async_lpop  sl     "335YY[
3C5	%IJ:	!"M!!Y. #D$6$6$<$<S$A!$D E ]Q%6(11e1D  #'#R#Rc5$ F    -11#u== yy{H :-I''BB(..&* C  &%("!==11 FD)c 24:2 /"=CDTDKK0DD MA    >" ! "!M" E  "!M"  	 yy{H :-I''BB(..&*	 C    I#a&R G!	s  6I)AG FG F)F*F.G 9F:G F3A,G F5 I)"G 6G :GG I)G I)G FG F0$F'%F0,G 5G G I)GG G GG I)GG 	I&%A<I!!I&&I))NNNr&   NNg      @r   )r&   )NN)<__name__
__module____qualname__r   rH   r@   r   r  rG   r	   rX   rY   r\   rb   rZ   r{   r(  r   r   r   r   r   cluster_pipeliner   r   r   r   r   r   r   r   r   r   rW   r   r   r   r   r   r   boolr   r+   r   r   r;   r  r  r  r	  r  r   r  r  r  r  r   r  r"  __classcell__)rM   s   @rN   r   r   .   sZ   
 *-#'(,*-U
 #3-U C=U  ~U !Un"	!#==	>"23 3 2 7;77$,UO7	7r,S , ,t ,\C C <M^H../ sCx) e_	
 
> IM9uS#X/96>uo9v(  	
 e_ 
"FF%-e_FP, "+/9 9 c]	9
 #4.9 
9v-  x~ 41d3i 1DI 18$s) 8S	 8 ,02"S	4#6672" #4.2" 
	2"j 7;0%-d^0j ,0E"S	4#667E" #4.E" 
	E"N"4 "H"D "H*T %%L/C /&<< <=< 
$u+		<0="#BC=	$u+	=~s x} 6 ,0	11 S	1 #4.	1 
1f#&/2	e$  $+/	DD }D #4.	D 
sDI~	Dr]   r   )+__doc__r   r=   r9   r   rq   datetimer   typingr   r   r   r   r   r	   r
   rD   litellm._loggingr   r   'litellm.litellm_core_utils.core_helpersr   litellm.types.cachingr   litellm.types.servicesr   
base_cacher   opentelemetry.tracer   _Spanr   r   r   redis.asyncio.clientr   redis.asyncio.clusterr   r   r.  rX   rY   r   r-   r]   rN   <module>r=     s          I I I  : U A / !11-5H&!-DH!$Di ir]   