
    AHjKW                        d dl Z d dlZd dlZd dlmZmZmZmZ d dlZd dl	m
Z d dlmZmZ d dlmZmZ d dlmZ ddlmZ d Zdd	Zdd
Zd Zd ZdedefdZ	 ddedee   defdZd Zd Zdej@                  fdZ!dejD                  fdZ#dejD                  fdZ$d Z%	 ddeejL                     deejD                  ej@                  f   fdZ'deejL                     fdZ(de)ddfdZ*y)    N)CallableListOptionalUnion)
get_secretget_secret_str)REDIS_CONNECTION_POOL_TIMEOUTREDIS_SOCKET_TIMEOUT)SensitiveDataMasker   )verbose_loggerc                      t        j                  t        j                        } h d}g d}| j                  D cg c]	  }||vs| c}|z   }|S c c}w )N>   selfretryconnection_pool)urlredis_connect_funcgcp_service_accountgcp_ssl_ca_certs)inspectgetfullargspecredisRedisargs)arg_specexclude_argsinclude_argsxavailable_argss        F/root/tools/cai/cai_env/lib/python3.12/site-packages/litellm/_redis.py_get_redis_kwargsr!      sR    %%ekk2HLL "*HA!<2GaH<WN Is   	AAc                     | t         j                  j                  } t        j                  t         j                  j                        }h d}dg}|j
                  D cg c]	  }||vs| c}|z   }|S c c}w )N>   r   r   r   r   )r   r   from_urlr   r   r   )clientr   r   r   r   r   s         r    _get_redis_url_kwargsr%   1   sl    ~%%%%ekk&:&:;HL 7L!)HA!<2GaH<WN Is   	A5)A5c                 &   | t         j                  j                  } t        j                  t         j
                        }h d}|j                  D cg c]	  }||vs| }}|j                  d       |j                  d       |j                  d       |j                  d       |j                  d       |j                  d       |j                  d       |j                  d	       |j                  d
       |j                  d       |S c c}w )N>   hostportr   r   startup_nodesr   passwordusernamesslssl_cert_reqsssl_check_hostnamessl_ca_certsr   r   r   max_connections)r   r   r#   r   r   RedisClusterr   append)r$   r   r   r   r   s        r    _get_redis_cluster_kwargsr3   D   s    ~%%%%e&8&89H YL!)HA!<2GaHNH*%*%% /*./.) /0,-+, Is   	DDc                  f    d} t               D ci c]  }|  |j                          | c}S c c}w )NREDIS_)r!   upper)PREFIXr   s     r    _get_redis_env_kwarg_mappingr8   ]   s2    F/@/BC!vhqwwyk"A%CCCs   .c                  x    t               } i }| j                         D ]  \  }}t        |d       }||||<    |S )N)default_value)r8   itemsr   )mappingreturn_dictkvvalues        r    _redis_kwargs_from_environmentrA   c   sK    *,GK #11D1"KN#     service_accountreturnc                     	 ddl m} |j                         }|j	                  | dg      }|j                  |      }t        |j                        S # t        $ r t        d      w xY w)a
  
    Generate GCP IAM access token for Redis authentication.

    Args:
        service_account: GCP service account in format 'projects/-/serviceAccounts/name@project.iam.gserviceaccount.com'

    Returns:
        Access token string for GCP IAM authentication
    r   )iam_credentials_v1zlgoogle-cloud-iam is required for GCP IAM Redis authentication. Install it with: pip install google-cloud-iamz.https://www.googleapis.com/auth/cloud-platform)namescope)request)google.cloudrF   ImportErrorIAMCredentialsClientGenerateAccessTokenRequestgenerate_access_tokenstraccess_token)rC   rF   r$   rI   responses        r    _generate_gcp_iam_access_tokenrR   n   s    
3  446F ;;?@ < G ++G+<Hx$$%%  
<
 	

s   A A(r/   c                       fd}|S )aq  
    Creates a custom Redis connection function for GCP IAM authentication.

    Args:
        service_account: GCP service account in format 'projects/-/serviceAccounts/name@project.iam.gserviceaccount.com'
        ssl_ca_certs: Path to SSL CA certificate file for secure connections

    Returns:
        A connection function that can be used with Redis clients
    c                    ddl m}m} ddlm} | j
                  j                  |        t              f} | j                  dg|ddi 	 | j                         } ||      d	k7  r |d
      y# |$ rK t        | d      r;| j                  r/| j                  d| j                  d       | j                         }n Y cw xY w)z8Initialize the connection and authenticate using GCP IAMr   )AuthenticationError$AuthenticationWrongNumberOfArgsError)str_if_bytesAUTHcheck_healthFr*   )rY   OKzGCP IAM authentication failedN)redis.exceptionsrU   rV   redis.utilsrW   _parser
on_connectrR   send_commandread_responsehasattrr*   )r   rU   rV   rW   	auth_argsauth_responserC   s         r    iam_connectz6create_gcp_iam_redis_connect_func.<locals>.iam_connect   s    	
 	-%3ODF	&A9A5A	 ..0M &$.%&EFF / 4 	tZ(T]]!!&$--e!L $ 2 2 4 		s   A2 2ACC )rC   r/   rd   s   `  r    !create_gcp_iam_redis_connect_funcrf      s    G4 rB   c                  n   dt         j                  v rt         j                  d   S dt         j                  vsdt         j                  vrt        d      dt         j                  v r't         j                  d   j                         dk(  rd} nd} d	}d
t         j                  v r=dt         j                  v r+t         j                  d
    dt         j                  d    d}n(dt         j                  v rt         j                  d    d}|  d| t         j                  d    dt         j                  d    S )N	REDIS_URL
REDIS_HOST
REDIS_PORTzUEither 'REDIS_URL' or both 'REDIS_HOST' and 'REDIS_PORT' must be specified for Redis.	REDIS_SSLtrueredissr    REDIS_USERNAMEREDIS_PASSWORD:@z://)osenviron
ValueErrorlower)redis_protocol	auth_parts     r    get_redis_url_from_environmentry      s   bjj zz+&&2::%RZZ)Gc
 	
 bjj RZZ%<%B%B%D%N!  I2::%*:bjj*Hzz"234AbjjAQ6R5SSTU		RZZ	'zz"234A6	SBJJ|,D+EQrzzR^G_F`aarB   c                  6   | j                         D ]J  \  }}t        |t              s|j                  d      s)|j	                  dd      }t        |      }|| |<   L i t               | }|j                  dd      xs t        d      }|)t        |t              rt        j                  |      |d<   n||j                  dd       |j                  dd      xs t        d      }|(t        |t              rt        j                  |      |d<   |j                  dd      xs t        d	      }|||d<   |j                  d
d      xs t        d      }|||d
<   |j                  d      xs t        d      }	|j                  d      xs t        d      }
|	lt        j                  d       t        |	|
      |d<   |	|d   _        |j                  dd       |j                  dd       |
r|j                  dd      r|
|d<   d|v r`|d   [|j                  d      sH|j                  dd       |j                  dd       |j                  dd       |j                  dd       |S d|v r|d   	 |S d|v r|d   	 |S d|vs|d   t!        d      |S )zO
    Common functionality across sync + async redis client implementations
    zos.environ/rn   r)   NREDIS_CLUSTER_NODESsentinel_nodesREDIS_SENTINEL_NODESsentinel_passwordREDIS_SENTINEL_PASSWORDservice_nameREDIS_SERVICE_NAMEr   REDIS_GCP_SERVICE_ACCOUNTr   REDIS_GCP_SSL_CA_CERTSzASetting up GCP IAM authentication for Redis with service account.)rC   r/   r   r,   Fr/   r   r'   r(   dbr*   z3Either 'host' or 'url' must be specified for redis.)r;   
isinstancerO   
startswithreplacer   rA   getjsonloadspopr   r   debugrf   _gcp_service_accountru   )env_overridesr>   r?   r@   redis_kwargs_startup_nodes_sentinel_nodes_sentinel_password_service_namer   _gcp_ssl_ca_certss              r    _get_redis_client_logicr      s(   
 ##% %1a!,,}"=		-,AqME$M!	%
(
*
L
 2>1A1A/SW1X 2\f]N !j&E(,

>(B_%		$/2>2B2BCSUY2Z 3^h_O "z/3'G)-O)D%&(4(8(8T) )3	1	2  %,>()#/#3#3ND#I $ZNM  '4^$ (++,AB n#G %(();<  A 'O	
 .O0?P.
)* CW)*? 	.5+T2 !1!1%!?+<L(e!4!@ 0VT*VT*T4(Z.  
L	(\/-J-V  	L(\:J-K-W
 	 
|	#|F';'CNOO rB   c                    t        d      }|	 t        j                  |      | d<   t        j                  d       ddlm} t               }i }| D ]  }||v s| |   ||<    g }| d   D ]  }|j                   |di |        |j                  dd        t        j                  dd|i|S # t        j                  $ r t	        d      w xY w)Nr{   r)   zbREDIS_CLUSTER_NODES environment variable is not valid JSON. Please ensure it's properly formatted.z8init_redis_cluster: startup nodes are being initialized.r   ClusterNodere   )r   r   r   JSONDecodeErrorru   r   r   redis.clusterr   r3   r2   r   r   r1   )r   _redis_cluster_nodes_in_envr   r   cluster_kwargsargnew_startup_nodesitems           r    init_redis_clusterr   -  s    1;<Q1R".	,0JJ7R,SL) ST)$&DN 4$;".s"3N34 ,._- 6  !4t!456 -P,=PPP) ## 	t 	s   B. .Cc                 
   | j                  d      }| j                  d      }| j                  d      }|r|st        d      t        j                  d       t	        j
                  |t        |      }|j                  |      S Nr|   r~   r   zIBoth 'sentinel_nodes' and 'service_name' are required for Redis Sentinel.z:init_redis_sentinel: sentinel nodes are being initialized.)socket_timeoutr*   )r   ru   r   r   r   Sentinelr
   
master_forr   r|   r~   r   sentinels        r    _init_redis_sentinelr   I  s    !%%&67N$(()<=##N3LW
 	
 UV ~~+"H |,,rB   c                 
   | j                  d      }| j                  d      }| j                  d      }|r|st        d      t        j                  d       t	        j
                  |t        |      }|j                  |      S r   )r   ru   r   r   async_redisr   r
   r   r   s        r    _init_async_redis_sentinelr   a  s    !%%&67N$(()<=##N3LW
 	
 UV ##+"H |,,rB   c                     t        di | }d|v rt        |      S d|v rD|d   ?t               }i }|D ]  }||v s||   ||<    t        j                  j
                  di |S d|v rd|v rt        |      S t        j                  di |S )Nr)   r   r|   r   re   )r   r   r%   r   r   r#   r   )r   r   r   
url_kwargsr   s        r    get_redis_clientr   y  s    *;];L,&!,//e!4!@$&
 	4Cd{".s"3
3	4 {{##1j11 <'Nl,J#L11;;&&&rB   r   c                    t        di |}d|v rBddlm} t               }i }|D ]  }||v s||   ||<    |j	                  dd       }ddlm} d }	|rt        |d      r|j                  }	n|j                  d      xs  |d      }	t        j                  d	|d u d
|	d u        |r>|	r<t        j                  d       	 t        |	      }
|
|d<   t        j                  d       nt        j                  d|d u d
|	d u        g }|d   D ]  }|j#                   |di |        |j	                  dd        t%        j&                  dd|i|}|S d|v r|d   | t%        j(                  |       S t+        t$        j(                  j,                        }i }|D ]3  }||v r	||   ||<   t        j                  dj/                  |             5 t%        j(                  j,                  di |S d|v rd|v rt1        |      S t3        |       | | |d<   t%        j(                  di |S # t        $ r+}t        j                  d|        ddlm}  |d      d }~ww xY w)Nr)   r   r   r   )r   r   r   r   z0DEBUG: Redis cluster kwargs: redis_connect_func=z, gcp_service_account_provided=zWDEBUG: Generating IAM token for service account (value not logged for security reasons)r*   zJDEBUG: Successfully generated GCP IAM access token for async Redis clusterz)Failed to generate GCP IAM access token: )rU   z'Failed to generate GCP IAM access tokenz3DEBUG: Not using GCP IAM auth - redis_connect_func=r   )r   )r$   zLREDIS: ignoring argument: {}. Not an allowed async_redis.Redis.from_url arg.r|   r   )r   r   re   )r   r   r   r3   r   litellmr   ra   r   r   r   r   rR   	Exceptionerrorr[   rU   r2   r   r1   r   r%   r#   formatr   _pretty_print_redis_config)r   r   r   r   r   r   r   r   r   r   rP   erU   r   r   cluster_clientr   s                    r    get_redis_async_clientr     s    +;];L,&-(* 	8Cd{&23&7s#	8
 ,//0DdK* #'*<>T"U"4"I"I"."2"2%# #= ;<   	>?QY]?]>^^}  R  Z^  ^  ~_  `	

 "5  iU=>QR-9z*$$`   EFX`dFdEe  fE  FY  ae  Fe  Ef  g 02 1 	:D$$[%84%89	:?D1 %11 
+
/=
 e!4!@&$$_EE$K,=,=,F,FG
 	Cd{".s"3
3$$bii		   ))7J77 <'Nl,J),77L9"*9&' 
 _  U$$'PQRPS%TU@)*STT	Us    %H, ,	I 5&II c                     t        d
i | }t        j                  d|       d|v ry d|v rF|d   At        |d   d}d|v r	 t	        |d         |d<   t        j                  j                  d
i |S t        j                  }d|v r't        j                  }|j                  dd        ||d<   t        j                  d
d	t        i|S # t
        t        f$ r t        j                  d|d          Y w xY w)Nz'get_redis_connection_pool: redis_kwargsr)   r   )timeoutr   r0   z1REDIS: invalid max_connections value %r, ignoringr,   connection_classr   re   )r   r   r   r	   int	TypeErrorru   warningr   BlockingConnectionPoolr#   
ConnectionSSLConnectionr   )r   r   pool_kwargsr   s       r    get_redis_connection_poolr     s     +;];LBLQ,&e!4!@4&
 ,14\BS5T1U-. 11::I[II"--&44%+;'(-- -1=  z* &&G !23s   C (C21C2r   c                    	 ddl }ddlm} ddlm} ddlm} ddlm} t        j                  |j                        sy |       }t               }|j                  |       } |dd	      }	 |d
ddd      }
|
j                  ddd       |
j                  dd	       |j                         D ]o  \  }}|	t!        |t"              r:|dk(  r|rdt%        |       d}n.|dk(  r|rdt%        |       d}nt'        |      }nt'        |      }|
j)                  ||       q d}|j+                  d      rd}n'|j+                  d      rd}n|j+                  d      rd} |dddd      }|j                  d dd       |j                  dd	       |j)                  d!|       |j-                  d"       |j-                   ||	d#$             |j-                  |       |j-                  |
       |j-                  d"       y# t.        $ r6 t               }|j                  |       }t        j0                  d%|        Y yt2        $ r"}t        j4                  d&|        Y d}~yd}~ww xY w)'zKPretty print the Redis configuration using rich with sensitive data maskingr   N)Console)Panel)Table)TextzRedis Configurationz	bold blue)styleu    🔧 Redis Connection ParametersTzbold magentaleft)titleshow_headerheader_styletitle_justify	Parametercyan)r   no_wrapValueyellowr)   [z cluster nodes]r|   z sentinel nodes]zStandard RediszRedis ClusterzRedis Sentinelr   zRedis (URL-based)u   📊 Connection Infoz
bold greenPropertyzConnection Type
blue)border_stylezRedis configuration: z+Error pretty printing Redis configuration: )loggingrich.consoler   
rich.panelr   
rich.tabler   	rich.textr   r   isEnabledForDEBUGr   	mask_dict
add_columnr;   r   listlenrO   add_rowr   printrK   infor   r   )r   r   r   r   r   r   consolemaskermasked_redis_kwargsr   config_tablekeyr@   	value_strconnection_type
info_tabler   s                    r    r   r     sj   SP($$"**7==9) %& %..|< *+> 4' 	
 	64Hx8 .335 	5JC eT*o-%&'E
|?$C	 00U&'E
|3C$D	$'J	 #E
I$$S)4	5$ +""?3-O $$%56.O $$U+1O (% 	

 	jEgX6,o> 	deE78j!l#d K$&$..|<34G3HIJ PJ1#NOOPs*   ;G? A7G? 6EG? ?<I'=I'I""I')N)+r   r   rs   typingr   r   r   r   r   redis.asyncioasyncior   r   r   r   litellm.constantsr	   r
   0litellm.litellm_core_utils.sensitive_data_maskerr   _loggingr   r!   r%   r3   r8   rA   rO   rR   rf   ry   r   r1   r   r   r   r   r   r   r   r   dictr   re   rB   r    <module>r      s=     
 2 2  # . Q P $,&2D&C &C &: #'))3-) )Xb0]@Q(:(: Q8-%++ -0-0A0A -0'. EI]k@@A] ;k6667]@k001BUPT UPd UPrB   