Ë
    uPêj¢†  ã            	       óX  — U d dl Z d dlZd dlZd dlmZmZ d dlmZ d dlm	Z	m
Z
 d dlZd dlmZ d dlmZ d dlmZmZ d dlmZmZmZ d dlmZmZmZ d d	lmZ d
dlmZ dZ ee!d<   d„ Z"de#de$e%   fd„Z&d6de#dz  de'e%df   fd„Z(d6d„Z)d„ Z*d„ Z+	 d6de%de%dz  defd„Z,	 	 	 d7de%dz  de%dz  de%dz  fd„Z-	 	 	 d7de%dz  de%dz  de%dz  de%fd„Z.	 	 	 d7de%dz  de%dz  de%dz  defd „Z/d!„ Z0d"e%de%fd#„Z1d$„ Z2dejf                  fd%„Z4d&e5de5fd'„Z6dejn                  fd(„Z8d)e5d*e%dz  de5fd+„Z9dejn                  fd,„Z:d-e;dz  dedz  fd.„Z<d&e5de5fd/„Z=d0„ Z>	 d6d1ej~                  dz  dejn                  ejf                  z  fd2„Z@dej~                  dz  fd3„ZAd&ee%e;f   dee%e;f   fd4„ZBd&e5ddfd5„ZCy)8é    N)ÚCallableÚMapping)ÚFinal)ÚurlsplitÚ
urlunsplit)ÚCredentialProvider)Ú
get_secretÚget_secret_str)ÚAzureADCredentialProviderÚGCPIAMCredentialProviderÚ_generate_gcp_iam_access_token)Ú#REDIS_CLUSTER_HEALTH_CHECK_INTERVALÚREDIS_CONNECTION_POOL_TIMEOUTÚREDIS_SOCKET_TIMEOUT)ÚSensitiveDataMaskeré   )Úverbose_loggerz https://redis.azure.com/.defaultÚAZURE_REDIS_SCOPEc                  óª   — t        j                  t        j                  «      } h d£}h d£}| j                  D �ch c]	  }||vsŒ|’Œ c}|z  }|S c c}w )N>   ÚselfÚretryÚconnection_pool>	   ÚurlÚazure_client_idÚazure_tenant_idÚgcp_ssl_ca_certsÚredis_connect_funcÚazure_client_secretÚcredential_providerÚgcp_service_accountÚazure_redis_ad_token)ÚinspectÚgetfullargspecÚredisÚRedisÚargs)Úarg_specÚexclude_argsÚinclude_argsÚxÚavailable_argss        úS/home/oem/CyberBrain26-unified/.venv/lib/python3.12/site-packages/litellm/_redis.pyÚ_get_redis_kwargsr-   )   sS   € Ü×,Ñ,¬U¯[©[Ó9€Hò€Lò
€Lð )1¯©ÖO 1¸À,Ò9NšQÒOÐR^Ñ^€NàÐùò Ps   º	AÁAÚclsÚreturnc                 óL   — t        d„ t        j                  | «      D «       «      S )u  Every ``__init__`` parameter accepted anywhere in a class's MRO.

    Keyword-only parameters are included, and the MRO is walked because redis-py splits a
    connection's parameters between ``AbstractConnection`` and its concrete subclasses.

    Each ``__init__`` is unwrapped before introspection: redis-py >= 7.4 decorates
    ``AbstractConnection.__init__`` with ``@deprecated_args``, whose wrapper is declared
    ``(self, *args, **kwargs)`` â€” introspecting the wrapper directly loses every real
    parameter (``socket_timeout`` included), which silently emptied this allowlist and
    dropped the socket timeouts from url-configured connections. ``inspect.unwrap``
    follows the ``__wrapped__`` chain to the true signature and is a no-op on
    undecorated ``__init__``s.
    c              3   óÐ   K  — | ]^  }|t         urTt        j                  t        j                  |j                  «      «      }|j
                  |j                  z   D ]  }|–— Œ Œ` y ­w©N)Úobjectr"   r#   ÚunwrapÚ__init__r&   Ú
kwonlyargs)Ú.0ÚklassÚspecÚnames       r,   ú	<genexpr>z"_init_arg_names.<locals>.<genexpr>R   s_   è ø€ ò àØœÑÜ×+Ñ+¬G¯N©N¸5¿>¹>Ó,JÓKˆDØ—I‘I §¡Ñ/òð
 ô	 	ðØñùs   ‚A$A&)Ú	frozensetr"   Úgetmro)r.   s    r,   Ú_init_arg_namesr>   D   s'   € ô ñ ä—^‘^ CÓ(ôó ð ó    Úclient.c                 óê   ‡— | €t         j                  } | t        j                  u rt        j                  nt         j                  }t	        h d£«      Šd}t        ˆfd„t        |«      D «       «      |z   S )a0  Connection kwargs that redis-py forwards from ``from_url`` down to the connection.

    ``from_url`` is declared as ``(cls, url, **kwargs)``, so introspecting it yields no
    connection kwargs at all. What it really does is hand its kwargs to the connection
    class, so that class's signature is the allowlist.

    Taking the client's signature instead would be wrong in both directions: it omits
    nothing useful, but it admits client-only parameters such as
    ``single_connection_client`` and ``auto_close_connection_pool``, plus the ``ssl_*``
    family that only ``SSLConnection`` accepts. Those reach ``AbstractConnection`` and
    raise ``TypeError`` the first time a connection is created. TLS on a url config is
    selected by the ``rediss://`` scheme, which picks ``SSLConnection`` on its own.
    >   r   r   r   )r   Úmax_connectionsc              3   ó,   •K  — | ]  }|‰vsŒ|–— Œ y ­wr2   © )r7   r*   r(   s     €r,   r;   z(_get_redis_url_kwargs.<locals>.<genexpr>x   s   øè ø€ ÒU�q¸qÈÒ?T”ÑUùs   ƒ	�)r$   r%   Úasync_redisÚ
Connectionr<   Útupler>   )r@   Úconnection_clsr)   r(   s      @r,   Ú_get_redis_url_kwargsrI   [   sf   ø€ ð €~Ü—‘ˆØ6<Ä×@QÑ@QÑ6QœK×2Ò2ÔW\×WgÑWg€Nä#ò	
ó€Lð 5€LäÓUœO¨NÓ;ÔUÓUÐXdÑdÐdr?   c                 óà   — | €t         j                  j                  } t        j                  t         j
                  «      }h d£}|j                  D �ch c]	  }||vsŒ|’Œ }}|h d£z  }|S c c}w )N>   ÚhostÚportr   r   Ústartup_nodesr   >   ÚsslÚpasswordÚusernameÚssl_ca_certsÚssl_cert_reqsÚsocket_timeoutr   r   rB   r   Úsocket_keepaliver   Ússl_check_hostnamer   r   r    r!   Úhealth_check_intervalÚsocket_connect_timeout)r$   r%   Úfrom_urlr"   r#   ÚRedisClusterr&   )r@   r'   r(   r*   r+   s        r,   Ú_get_redis_cluster_kwargsrZ   {   so   € Ø€~Ü—‘×%Ñ%ˆÜ×,Ñ,¬U×-?Ñ-?Ó@€Hò `€Là!)§¡ÖH˜A°!¸<Ò2G’aÐH€NÐHØò ñ €Nð, Ðùò/ Is   Á	A+ÁA+c                  óˆ   — d} t        dh«      }t        «       D �ci c]  }||vsŒ| › |j                  «       › �|“Œ c}S c c}w )NÚREDIS_r   )r<   r-   Úupper)ÚPREFIXÚexclude_from_environmentr*   s      r,   Ú_get_redis_env_kwarg_mappingr`   �   sI   € Ø€Fä&/Ð1FÐ0GÓ&HÐÜ/@Ó/BÖh¨!ÀaÐOgÒFgˆvˆh�q—w‘w“y�kÐ" AÑ%ÒhÐhùÒhs   ›	?¥?c                  óx   — t        «       } i }| j                  «       D ]  \  }}t        |d ¬«      }|€Œ|||<   Œ |S )N)Údefault_value)r`   Úitemsr	   )ÚmappingÚreturn_dictÚkÚvÚvalues        r,   Ú_redis_kwargs_from_environmentri   ¤   sK   € Ü1Ó3€Gà€KØ—‘“ò #‰ˆˆ1Ü˜1¨DÔ1ˆØÑØ"ˆK˜ŠNð#ð Ðr?   Úservice_accountrQ   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_healthFrO   ©rs   ÚOKzGCP IAM authentication failedN)Úredis.exceptionsrn   ro   Úredis.utilsrq   Ú_parserÚ
on_connectr   Úsend_commandÚread_responseÚhasattrrO   )r   rn   ro   rq   Ú	auth_argsÚauth_responserj   s         €r,   Úiam_connectz6create_gcp_iam_redis_connect_func.<locals>.iam_connect¾   sÉ   ø€ ÷	
õ 	-à�‰×Ñ Ô%ä:¸?ÓKÐMˆ	Øˆ×Ñ˜&ÐA 9ÒA¸5ÒAð	Ø ×.Ñ.Ó0ˆMñ ˜Ó&¨$Ò.Ù%Ð&EÓFÐFð /øð 4ò 	ä�t˜ZÔ(¨T¯]ª]Ø×!Ñ! &¨$¯-©-ÀeÐ!ÔLØ $× 2Ñ 2Ó 4‘àñ ð		ús   ÁA2 Á2ACÃCrD   )rj   rQ   r   s   `  r,   Ú!create_gcp_iam_redis_connect_funcr€   ¯   s   ø€ ôGð4 Ðr?   r   r   r   c                 ó`  — 	 ddl m}m}m} | xs t
        j                  j                  d«      }|xs t
        j                  j                  d«      }|xs t
        j                  j                  d«      }|r|r|r ||||¬«      S |r	 ||¬«      S  |«       S # t        $ r t	        d«      ‚w xY w)	zÊ
    Build a long-lived Azure credential object.

    Azure SDK credentials cache tokens internally and handle expiry/refresh
    transparently, so this should be called once and the result reused.
    r   )ÚClientSecretCredentialÚDefaultAzureCredentialÚManagedIdentityCredentialziazure-identity is required for Azure AD Redis authentication. Install it with: pip install azure-identityÚAZURE_CLIENT_IDÚAZURE_TENANT_IDÚAZURE_CLIENT_SECRET)Ú	client_idÚ	tenant_idÚclient_secret)rˆ   )Úazure.identityr‚   rƒ   r„   ÚImportErrorÚosÚenvironÚget)	r   r   r   r‚   rƒ   r„   Ú
_client_idÚ
_tenant_idÚ_client_secrets	            r,   Ú_build_azure_credentialr“   Û   s²   € ð	
÷	
ñ 	
ð (ÒL¬2¯:©:¯>©>Ð:KÓ+L€JØ'ÒL¬2¯:©:¯>©>Ð:KÓ+L€JØ/ÒX´2·:±:·>±>ÐBWÓ3X€Ná‘j¡^Ù%Ø Ø Ø(ô
ð 	
ñ
 
Ù(°:Ô>Ð>á%Ó'Ð'øô% ò 
ÜØwó
ð 	
ð
ús   ‚
B ÂB-c                 ó`   — t        | ||¬«      }|j                  t        «      }|j                  S )uÃ  
    One-shot helper that builds a credential and fetches a single Azure AD
    access token for Redis. Each call rebuilds the credential and performs a
    network round-trip, so it should not be used in steady-state Redis flows
    â€” the sync (``create_azure_ad_redis_connect_func``) and async paths
    (``AzureADCredentialProvider``) keep the credential alive across
    connections so the Azure SDK's internal cache + silent refresh apply.
    ©r   r   r   )r“   Ú	get_tokenr   Útoken)r   r   r   Ú
credentialr—   s        r,   Ú_generate_azure_ad_redis_tokenr™     s4   € ô 0Ø'Ø'Ø/ô€Jð
 ×'Ñ'Ô(9Ó:€EØ�;‰;Ðr?   c                 ó<   ‡— t        | ||¬«      Šˆfd„}‰|_        |S )uF  
    Creates a custom Redis connection function for Azure AD authentication.

    Used for sync Redis clients. The credential is created once (captured by the
    closure) and reused across connections â€” the Azure SDK handles token caching
    and silent renewal internally. Only ``get_token`` is called per connection.
    r•   c                 ó¼  •— ddl m}m} ddlm} | j
                  j                  | «       ‰j                  t        «      j                  }t        j                  j                  dd«      }|r||f}n|f} | j                  dg|¢­ddiŽ 	 | j                  «       } ||«      d
k7  r |d«      ‚y# |$ r' | j                  d|d¬	«       | j                  «       }Y Œ?w xY w)z9Initialize the connection and authenticate using Azure ADr   rm   rp   ÚREDIS_USERNAMEÚ rr   rs   Frt   ru   z(Azure AD authentication failed for RedisN)rv   rn   ro   rw   rq   rx   ry   r–   r   r—   r�   rŽ   r�   rz   r{   )	r   rn   ro   rq   Úaccess_tokenrP   r}   r~   r˜   s	           €r,   Ú
ad_connectz6create_azure_ad_redis_connect_func.<locals>.ad_connect)  sâ   ø€ ÷	
õ 	-à�‰×Ñ Ô%à(×2Ñ2Ô3DÓE×KÑKˆô Ÿ*™*Ÿ.™.Ð)9¸2Ó>ˆÙØ! <Ð0‰Ià%˜ˆIàˆ×Ñ˜&ÐA 9ÒA¸5ÒAð	1Ø ×.Ñ.Ó0ˆMñ ˜Ó&¨$Ò.Ù%Ð&PÓQÐQð /øð 4ò 	1à×Ñ˜f lÀÐÔGØ ×.Ñ.Ó0ŠMð	1ús   ÂB/ Â/)CÃC)r“   Ú_azure_credential)r   r   r   rŸ   r˜   s       @r,   Ú"create_azure_ad_redis_connect_funcr¡     s/   ø€ ô 0Ø'Ø'Ø/ô€JôRðH $.€JÔ ØÐr?   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$   r�   rœ   ÚREDIS_PASSWORDú:ú@z://)r�   rŽ   Ú
ValueErrorÚlower)Úredis_protocolÚ	auth_parts     r,   Úget_redis_url_from_environmentr°   Q  s  € Ø”b—j‘jÑ Ü�z‰z˜+Ñ&Ð&àœ2Ÿ:™:Ñ%¨¼R¿Z¹ZÑ)GÜÐpÓqÐqà”b—j‘jÑ ¤R§Z¡Z°Ñ%<×%BÑ%BÓ%DÈÒ%NØ!‰à ˆð €IØœ2Ÿ:™:Ñ%Ð*:¼b¿j¹jÑ*HÜ—z‘zÐ"2Ñ3Ð4°A´b·j±jÐAQÑ6RÐ5SÐSTÐU‰	Ø	œRŸZ™ZÑ	'Ü—z‘zÐ"2Ñ3Ð4°AÐ6ˆ	àÐ˜S  ¬B¯J©J°|Ñ,DÐ+EÀQÄrÇzÁzÐR^ÑG_ÐF`ÐaÐar?   r   c                 óÆ   — t        | «      }|j                  j                  dd«      d   }t        |j                  ||j
                  |j                  |j                  f«      S )Nr«   r   éÿÿÿÿ)r   ÚnetlocÚrsplitr   ÚschemeÚpathÚqueryÚfragment)r   Úpartsr³   s      r,   Ú_url_without_userinforº   g  sL   € Ü˜C“=€EØ—L‘L×'Ñ'¨¨QÓ/°Ñ3€FÜ�u—|‘| V¨U¯Z©Z¸¿¹ÀeÇnÁnÐUÓVÐVr?   c                  óü  ‡ — ‰ j                  «       D ]J  \  }}t        |t        «      sŒ|j                  d«      sŒ)|j	                  dd«      }t        |«      }|‰ |<   ŒL t        «       }t        ˆ fd„dD «       «      }|r#‰ j                  d«      €|j                  dd«       i |¥‰ ¥}|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«      �€m|j                  d«      xs t        d«      }|j                  d«      xs t        d«      }|�Ht        j                  d«       t        ||¬«      |d<   ||d   _        |r|j                  dd«      r||d<   |j                  d«      xs t        d«      }|duxr t        |«      j#                  «       dk(  }|r|�t        j$                  d«       |rŒ|€Š|j                  d«      xs t        d«      }|j                  d «      xs t        d!«      }|j                  d"«      xs t        d#«      }t        j                  d$«       t'        |||¬%«      |d<   d&|d   _        |j                  dd«       |j                  dd«       |j                  dd«       |j                  dd«       |j                  d d«       |j                  d"d«       |j                  d«      �X|j                  dd«       |j                  d'd«       |j                  d(d«       |j                  d«      �t+        |d   «      |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   €	d	|v r|d	   �	 |S d)|vs|d)   €t-        d,«      ‚|S )-zO
    Common functionality across sync + async redis client implementations
    zos.environ/r�   c              3   óD   •K  — | ]  }‰j                  |«      d u–— Œ y ­wr2   )r�   )r7   ÚkeyÚenv_overridess     €r,   r;   z*_get_redis_client_logic.<locals>.<genexpr>}  s&   øè ø€ ò 'Ø/2ˆ×Ñ˜#Ó dÔ*ñ'ùs   ƒ )rK   rM   Úsentinel_nodesr   NrM   ÚREDIS_CLUSTER_NODESr¿   ÚREDIS_SENTINEL_NODESÚsentinel_passwordÚREDIS_SENTINEL_PASSWORDÚservice_nameÚREDIS_SERVICE_NAMEr   r    ÚREDIS_GCP_SERVICE_ACCOUNTr   ÚREDIS_GCP_SSL_CA_CERTSzASetting up GCP IAM authentication for Redis with service account.)rj   rQ   r   rN   FrQ   r!   ÚREDIS_AZURE_AD_TOKENr§   z•Both GCP IAM (gcp_service_account) and Azure AD (azure_redis_ad_token) are configured for Redis. Using GCP IAM. Remove one to avoid misconfiguration.r   r…   r   r†   r   r‡   z-Setting up Azure AD authentication for Redis.r•   TrP   rO   rK   rL   Údbz3Either 'host' or 'url' must be specified for redis.)rc   Ú
isinstanceÚstrÚ
startswithÚreplacer	   ri   Úanyr�   ÚpopÚjsonÚloadsr
   r   Údebugr€   Ú_gcp_service_accountr­   Úwarningr¡   Ú_azure_redis_ad_tokenrº   r¬   )r¾   rf   rg   rh   Úenvironment_kwargsÚcaller_named_a_targetÚredis_kwargsÚ_startup_nodesÚ_sentinel_nodesÚ_sentinel_passwordÚ_service_namerÓ   Ú_gcp_ssl_ca_certsrÕ   Ú_azure_ad_enabledÚ_azure_client_idÚ_azure_tenant_idÚ_azure_client_secrets   `                 r,   Ú_get_redis_client_logicrâ   m  s  ø€ ð
 ×#Ñ#Ó%ò %‰ˆˆ1Ü�aœÕ !§,¡,¨}Õ"=Ø—	‘	˜-¨Ó,ˆAÜ˜q“MˆEØ$ˆM˜!Òð	%ô !?Ó @Ðô
 $'ó 'Ø6aô'ó $Ðñ  ×!2Ñ!2°5Ó!9Ð!AØ×Ñ˜u dÔ+ðØ
ðà
ð€Lð
 0<×/?Ñ/?ÀÐQUÓ/Vò 0ÔZdØó[€Nð Ð!¤j°ÄÔ&EÜ(,¯
©
°>Ó(Bˆ�_Ò%Ø	Ð	Ø×Ñ˜¨$Ô/à0<×0@Ñ0@ÐAQÐSWÓ0Xò 1Ô\fØó]€Oð Ð"¤z°/Ä3Ô'GÜ)-¯©°OÓ)DˆÐ%Ñ&à,8×,<Ñ,<Ð=PÐRVÓ,Wò -Ô[iØ!ó\Ðð Ð%Ø,>ˆÐ(Ñ)à'3×'7Ñ'7¸ÈÓ'MÒ'qÔQ[Ð\pÓQq€MàÐ Ø'4ˆ�^Ñ$à×ÑÐ-Ó.Ñ6à&2×&6Ñ&6Ð7LÓ&Mò '
ÔQ_Ø'óR
Ðð $0×#3Ñ#3Ð4FÓ#GÒ#sÌ>ÐZrÓKsÐàÐ+Ü× Ñ Ð!dÔeÜ1RØ 4ÐCTô2ˆLÐ-Ñ.ð G[ˆLÐ-Ñ.ÔCñ ! \×%5Ñ%5°e¸UÔ%CØ/@�˜^Ñ,ð (4×'7Ñ'7Ð8NÓ'OÒ'uÔS]Ð^tÓSuÐà#8ÀÐ#DÒ#uÌÐMbÓIc×IiÑIiÓIkÐouÑIuÐáÐ!5Ð!AÜ×"Ñ"ðGôñ
 Ð!5Ð!=Ø&2×&6Ñ&6Ð7HÓ&IÒ&nÌ^Ð\mÓMnÐØ&2×&6Ñ&6Ð7HÓ&IÒ&nÌ^Ð\mÓMnÐØ*6×*:Ñ*:Ð;PÓ*Qò +ÔUcØ%óVÐ ô × Ñ Ð!PÔQÜ1SØ 0Ø 0Ø$8ô2ˆLÐ-Ñ.ð HLˆLÐ-Ñ.ÔDà×ÑÐ*¨DÔ1Ø×ÑÐ'¨Ô.ð ×ÑÐ+¨TÔ2Ø×ÑÐ&¨Ô-Ø×ÑÐ&¨Ô-Ø×ÑÐ*¨DÔ1à×ÑÐ-Ó.Ð:Ø×ÑÐ-¨tÔ4Ø×Ñ˜ TÔ*Ø×Ñ˜ TÔ*Ø×Ñ˜EÓ"Ð.Ü"7¸ÀUÑ8KÓ"LˆL˜Ñà�Ñ ¨eÑ!4Ð!@ð ×Ñ Ô0Ø×Ñ˜V TÔ*Ø×Ñ˜V TÔ*Ø×Ñ˜T 4Ô(Ø×Ñ˜Z¨Ô.ð Ðð 	˜<Ñ'Ø˜Ñ)Ð5Ø˜|Ñ+ØÐ)Ñ*Ð6àð
 Ðð	 
�|Ñ	# |°FÑ';Ð'CÜÐNÓOÐOð Ðr?   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À   rM   zbREDIS_CLUSTER_NODES environment variable is not valid JSON. Please ensure it's properly formatted.z8init_redis_cluster: startup nodes are being initialized.r   ©ÚClusterNoderD   )r	   rÐ   rÑ   ÚJSONDecodeErrorr¬   r   rÒ   Úredis.clusterrå   rZ   ÚappendrÏ   r$   rY   )rØ   Ú_redis_cluster_nodes_in_envrå   r&   Úcluster_kwargsÚargÚnew_startup_nodesÚitems           r,   Úinit_redis_clusterrî   ÿ  sø   € Ü5?Ð@UÓ5VÐØ"Ð.ð	Ü,0¯J©JÐ7RÓ,SˆL˜Ñ)ô ×ÑÐSÔTÝ)ä+Ó-€DØ€NØò 4ˆØ�$Š;Ø".¨sÑ"3ˆN˜3Òð4ð 35Ðà˜_Ñ-ò 6ˆØ× Ñ ¡Ñ!4¨tÑ!4Õ5ð6ð ×Ñ�¨Ô-Ü×ÑÑPÐ,=ÐPÀÑPÐPøô) ×#Ñ#ò 	ÜØtóð ð	ús   �B. Â.CrØ   c                 óF   — i }t        «       }| D ]  }||v sŒ| |   ||<   Œ |S r2   )r-   )rØ   Úconnection_kwargsr&   rë   s       r,   Ú%_get_redis_sentinel_connection_kwargsrñ     s>   € Ø!ÐÜ#Ó%€DØò 7ˆØ�$Š;Ø%1°#Ñ%6Ð˜cÒ"ð7ð Ðr?   c                 ó^  — | j                  d«      }| j                  d«      }| j                  d«      }t        | «      }|j                  dt        «       t	        ||«      }|r|st        d«      ‚t        j                  d«       t        j                  ||¬«      } |j                  |fi |¤ŽS ©Nr¿   rÂ   rÄ   rS   zIBoth 'sentinel_nodes' and 'service_name' are required for Redis Sentinel.z:init_redis_sentinel: sentinel nodes are being initialized.)Úsentinel_kwargs)r�   rñ   Ú
setdefaultr   Ú_sentinel_auth_kwargsr¬   r   rÒ   r$   ÚSentinelÚ
master_for©rØ   r¿   rÂ   rÄ   rð   rô   Úsentinels          r,   Ú_init_redis_sentinelrû   %  s±   € Ø(×,Ñ,Ð-=Ó>€NØ+×/Ñ/Ð0CÓDÐØ&×*Ñ*¨>Ó:€LÜDÀ\ÓRÐØ× Ñ Ð!1Ô3GÔHÜ2Ð3DÐFWÓX€Oá¡ÜÐdÓeÐeä×ÑÐUÔVô —n‘nØØ'ô€Hð ˆ8×Ñ˜|ÑAÐ/@ÑAÐAr?   rð   rÂ   c                 óJ   — d„ | j                  «       D «       }t        ||¬«      S )a4  The Sentinel monitors are separate servers that authenticate with their own password, so the
    data node's credential provider never belongs on them: leaving it there makes redis-py send the
    data node's token to a monitor, which fails whether the monitor is unauthenticated or has its
    own password.c              3   ó6   K  — | ]  \  }}|d k7  sŒ||f–— Œ y­w)r   NrD   )r7   rf   rg   s      r,   r;   z(_sentinel_auth_kwargs.<locals>.<genexpr>B  s    è ø€ Ò^™d˜a À1ÐH]ÓC]�A�q”6Ñ^ùs   ‚�	)rO   )rc   Údict)rð   rÂ   Úkepts      r,   rö   rö   =  s'   € ñ
 _Ð&7×&=Ñ&=Ó&?Ô^€DÜ�Ð0Ô1Ð1r?   c                 ó^  — | j                  d«      }| j                  d«      }| j                  d«      }t        | «      }|j                  dt        «       t	        ||«      }|r|st        d«      ‚t        j                  d«       t        j                  ||¬«      } |j                  |fi |¤ŽS ró   )r�   rñ   rõ   r   rö   r¬   r   rÒ   rE   r÷   rø   rù   s          r,   Ú_init_async_redis_sentinelr  F  s³   € Ø(×,Ñ,Ð-=Ó>€NØ+×/Ñ/Ð0CÓDÐØ&×*Ñ*¨>Ó:€LÜDÀ\ÓRÐØ× Ñ Ð!1Ô3GÔHÜ2Ð3DÐFWÓX€Oá¡ÜÐdÓeÐeä×ÑÐUÔVô "×*Ñ*ØØ'ô€Hð ˆ8×Ñ˜|ÑAÐ/@ÑAÐAr?   r   c                 ó²   — t        | dd«      }|�t        |«      S t        | dd«      }|�.t        |t        j                  j                  d«      xs d¬«      S y)aí  The Azure AD and GCP IAM connect funcs run their AUTH exchange with the blocking client
    API, so on an async connection their ``send_command``/``read_response`` calls return
    coroutines nobody awaits and every connect fails. Async paths authenticate through a
    ``CredentialProvider`` instead, which redis-py consults per connection so the token stays
    fresh. Any other ``redis_connect_func`` is left where it is, since redis-py awaits it
    itself when it is a coroutine function.rÓ   Nr    rœ   )rP   )Úgetattrr   r   r�   rŽ   r�   )r   r    Úazure_credentials      r,   Ú_async_credential_providerr  ^  sd   € ô ")Ð);Ð=SÐUYÓ!ZÐØÐ&Ü'Ð(;Ó<Ð<ä%Ð&8Ð:MÈtÓTÐØÐ#Ü(Ð)9ÄBÇJÁJÇNÁNÐScÓDdÒDlÐhlÔmÐmàr?   c                 óÐ   ‡— | j                  d«      }|�|nt        | j                  d«      «      }|€| S t        h d£«      Šˆfd„| j                  «       D «       }t	        ||¬«      S )z³Swaps a connect func an async path cannot run for the equivalent credential provider,
    which supersedes any static username or password redis-py would otherwise reject it with.r   r   >   rO   rP   r   c              3   ó6   •K  — | ]  \  }}|‰vsŒ||f–— Œ y ­wr2   rD   )r7   rf   rg   Ú
supersededs      €r,   r;   z%_async_auth_kwargs.<locals>.<genexpr>}  s    øè ø€ ÒR™d˜a ¸aÀzÒ>Q�A�q”6ÑRùs   ƒ�	)r   )r�   r  r<   rc   rþ   )rØ   Úexplicit_providerr   rÿ   r  s       @r,   Ú_async_auth_kwargsr
  p  sw   ø€ ð  ,×/Ñ/Ð0EÓFÐð Ð(ñ 	ä'¨×(8Ñ(8Ð9MÓ(NÓOð ð
 Ð"ØÐä!Ò"PÓQ€JÛR l×&8Ñ&8Ó&:ÔR€DÜ�Ð*=Ô>Ð>r?   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 )NrM   r   r¿   rÄ   rD   )râ   rî   rI   r$   r%   rX   rû   )r¾   rØ   r&   Ú
url_kwargsrë   s        r,   Úget_redis_clientr  �  s­   € Ü1ÑB°MÑB€Là˜,Ñ&Ü! ,Ó/Ð/à�Ñ ¨eÑ!4Ð!@Ü+Ó-ˆØˆ
Øò 	4ˆCØ�dŠ{Ø".¨sÑ"3�
˜3’ð	4ô �{‰{×#Ñ#Ñ1 jÑ1Ð1ð ˜<Ñ'¨N¸lÑ,JÜ# LÓ1Ð1ä�;‰;Ñ&˜Ñ&Ð&r?   r   c                 ó  — t        t        di |¤Ž«      }d|v r®ddlm} t	        «       }i }|D ]  }||v sŒ||   ||<   Œ g }|d   D ]  }|j                   |di |¤Ž«       Œ |j                  dd «       |j                  dd «       |j                  dt        «       |j                  dd«       ddl	m
}	  |	«       }
 |
dd|i|¤Ž}|S d	|v r‚|d	   �}| �t        j                  | ¬
«      S t        t        j                  ¬«      }i }|D ]%  }||v r	||   ||<   Œt        j                  d|«       Œ' t        j                  j                   di |¤ŽS d|v rd|v rt#        |«      S t%        |¬«       | �| |d<   t        j                  di |¤ŽS )NrM   r   rä   r   rV   rT   T)Ú%get_litellm_async_redis_cluster_classr   )r   ©r@   zLREDIS: ignoring argument: %s. Not an allowed async_redis.Redis.from_url arg.r¿   rÄ   )rØ   r   rD   )r
  râ   rç   rå   rZ   rè   rÏ   rõ   r   Ú,litellm.caching.redis_cluster_node_isolationr  rE   r%   rI   r   rÒ   rX   r  Ú_pretty_print_redis_config)r   r¾   rØ   rå   r&   rê   rë   rì   rí   r  Úasync_redis_cluster_classÚcluster_clientr  s                r,   Úget_redis_async_clientr  —  sã  € ô -Ô-DÑ-UÀ}Ñ-UÓV€Là˜,Ñ&Ý-ä(Ó*ˆØ "ˆØò 	8ˆCØ�dŠ{Ø&2°3Ñ&7�˜sÒ#ð	8ð 79Ðà  Ñ1ò 	:ˆDØ×$Ñ$¡[Ñ%8°4Ñ%8Õ9ð	:à×Ñ˜?¨DÔ1Ø×ÑÐ/°Ô6ð 	×!Ñ!Ð"9Ô;^Ô_Ø×!Ñ!Ð"4°dÔ;õ	
ñ ,QÓ+RÐ!ñ !:ñ !
Ø+ð!
àñ!
ˆð
 Ðà�Ñ ¨eÑ!4Ð!@ØÐ&Ü×$Ñ$°_ÔEÐEÜ$¬K×,=Ñ,=Ô>ˆØˆ
Øò 	ˆCØ�d‰{Ø".¨sÑ"3�
˜3’ä×$Ñ$ØbÐdgõð		ô × Ñ ×)Ñ)Ñ7¨JÑ7Ð7ð ˜<Ñ'¨N¸lÑ,JÜ)¨,Ó7Ð7ä¨LÕ9àÐ"Ø*9ˆÐ&Ñ'ä×Ññ Ø
ñð r?   c                  óv  — t        t        d
i | ¤Ž«      }t        j                  d|«       d|v ry d|v r“|d   �Žt	        t
        j                  ¬«      }|j                  «       D ��ci c]  \  }}||v sŒ|dk7  sŒ||“Œ }}}t        |d<   |d   |d<   d|v r	 t        |d   «      |d<   t        j                  j                  d
i |¤ŽS |j                  dd «      rt
        j                   |d	<   t        j                  d
dt        i|¤ŽS c c}}w # t        t        f$ r t        j                  d|d   «       Y Œ�w xY w)Nz'get_redis_connection_pool: redis_kwargsrM   r   r  rB   Útimeoutz1REDIS: invalid max_connections value %r, ignoringrN   Úconnection_classrD   )r
  râ   r   rÒ   rI   rE   r%   rc   r   ÚintÚ	TypeErrorr¬   rÔ   ÚBlockingConnectionPoolrX   rÏ   ÚSSLConnection)r¾   rØ   Úallowed_argsrf   rg   Úpool_kwargss         r,   Úget_redis_connection_poolr  à  sS  € ô -Ô-DÑ-UÀ}Ñ-UÓV€LÜ×ÑÐBÀLÔQà˜,Ñ&Øà�Ñ ¨eÑ!4Ð!@Ü3¼;×;LÑ;LÔMˆØ/;×/AÑ/AÓ/C×t¡t q¨!ÀqÈLÒGXÐ]^ÐbsÓ]s˜a ™dÐtˆÑtÜ!>ˆ�IÑØ)¨%Ñ0ˆ�EÑØ Ñ,ðÜ14°\ÐBSÑ5TÓ1U�Ð-Ñ.ô ×1Ñ1×:Ñ:ÑI¸[ÑIÐIà×Ñ˜˜tÔ$Ü+6×+DÑ+DˆÐ'Ñ(Ü×-Ñ-ÑdÔ6SÐdÐWcÑdÐdùó uøô œzÐ*ò Ü×&Ñ&ØGØ Ð!2Ñ3öðús$   Á&DÁ3DÁ9DÂD Ä(D8Ä7D8c                 óz   — | j                  «       D ��ci c]  \  }}||dk(  r|�dn
|dk(  r|�dn|“Œ c}}S c c}}w )Nr   z<credential provider>r   z<redis connect function>)rc   )rØ   r½   rh   s      r,   Ú_redis_kwargs_for_loggingr!  ý  sc   € ð '×,Ñ,Ó.÷ñ ˆC�ð 	ØÐ'Ò'¨EÐ,=ñ %ð Ð&Ò&¨5Ð+<ñ (àñ		óð ùó s   ”7c                 óâ  — t        | «      }	 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# t0        $ r4 t        «       }|j                  |«      }	t        j2                  d%|	«       Y yt4        $ r }t        j6                  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ÚyellowrM   ú[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: %sz-Error pretty printing Redis configuration: %s)r!  ÚloggingÚrich.consoler#  Ú
rich.panelr$  Ú
rich.tabler%  Ú	rich.textr&  r   ÚisEnabledForÚDEBUGr   Ú	mask_dictÚ
add_columnrc   rÊ   ÚlistÚlenrË   Úadd_rowr�   ÚprintrŒ   ÚinfoÚ	ExceptionÚerror)rØ   Úredis_kwargs_for_loggingr7  r#  r$  r%  r&  ÚconsoleÚmaskerÚmasked_redis_kwargsr)  Úconfig_tabler½   rh   Ú	value_strÚconnection_typeÚ
info_tableÚes                     r,   r  r    sl  € ä&?ÀÓ&MÐðSQÛå(Ý$Ý$Ý"ä×*Ñ*¨7¯=©=Ô9Øá ›ˆô %Ó&ˆð %×.Ñ.Ð/GÓHÐñ Ð1¸ÔEˆñ $Ø4ØØ'Ø ô	
ˆð 	×Ñ °6À4ÐÔHØ×Ñ ¨xÐÔ8ð .×3Ñ3Ó5ò 	5‰JˆC�ØÑ ä˜e¤TÔ*Ø˜oÒ-±%à&'¬¨E«
 |°?Ð$C™	ØÐ 0Ò0±Uà&'¬¨E«
 |Ð3CÐ$D™	ä$'¨£J™	ä # E£
�Ià×$Ñ$ S¨)Õ4ð	5ð$ +ˆØ×"Ñ" ?Ô3Ø-‰OØ ×$Ñ$Ð%5Ô6Ø.‰OØ ×$Ñ$ UÔ+Ø1ˆOñ "Ø(ØØ%Ø ô	
ˆ
ð 	×Ñ˜j°ÀÐÔEØ×Ñ˜g¨XÐÔ6Ø×ÑÐ,¨oÔ>ð 	�‰�dÔØ�‰‘e˜E°Ô7Ô8Ø�‰�jÔ!Ø�‰�lÔ#Ø�‰�dÕøäò Lä$Ó&ˆØ$×.Ñ.Ð/GÓHÐÜ×ÑÐ5Ð7JÖKÜò QÜ×ÑÐLÈa×PÑPûðQús+   �;H
 Á	A7H
 ÃEH
 È
:I.ÉI.ÉI)É)I.r2   )NNN)Dr"   rÐ   r�   Úcollections.abcr   r   Útypingr   Úurllib.parser   r   r$   Úredis.asyncioÚasynciorE   Úredis.credentialsr   Úlitellmr	   r
   Ú"litellm._redis_credential_providerr   r   r   Úlitellm.constantsr   r   r   Ú0litellm.litellm_core_utils.sensitive_data_maskerr   Ú_loggingr   r   Ú__annotations__r-   Útyper<   rË   r>   rG   rI   rZ   r`   ri   r€   r“   r™   r¡   r°   rº   râ   rY   rî   rþ   rñ   r%   rû   rö   r  r3   r  r
  r  r  r  r  r!  r  rD   r?   r,   ú<module>r]     sÜ  ðô Û ó 
ß -Ý ß -ã Ý #Ý 0ç .÷ñ ÷
ñ õ
 Qå $à=Ð �5Ó =òð6˜ð  )¨C¡.ó ñ.e $¨¡+ð e¸¸sÀC¸x¹ó eó@òDiòð  $ñ)Øð)à˜‘*ð)ð ó)ðZ #'Ø"&Ø&*ñ#(Ø˜4‘Zð#(à˜4‘Zð#(ð ˜t™ó#(ðN #'Ø"&Ø&*ñØ˜4‘Zðà˜4‘Zðð ˜t™ðð 	ó	ð. #'Ø"&Ø&*ñ7Ø˜4‘Zð7à˜4‘Zð7ð ˜t™ð7ð ó	7òtbð,W˜sð W só WòOðdQ¨×(:Ñ(:ó Qð8¸ð Àó ðB¨%¯+©+ó Bð02¨Tð 2ÀcÈDÁjð 2ÐUYó 2ðB°×0AÑ0Aó Bð0°6¸D±=ð ÐEWÐZ^ÑE^ó ð$? Tð ?¨dó ?ò"'ð. BFñFØ ×7Ñ7¸$Ñ>ðFð ×Ñ˜×1Ñ1Ñ1óFðReà×'Ñ'¨$Ñ.óeð:¨G°C¸°KÑ,@ð ÀWÈSÐRXÈ[ÑEYó ðVQ¨Tð VQ°dô VQr?   