
    iz                         d dl Z d dlZd dlmZ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mZmZ d dlZd dlmZ d dlmZ d dlmZ d dlmZ d dlmZ d d	lmZ d d
lmZ d dl m!Z!  e       Z" G d de      Z#de	ejH                  e%f   de%fdZ&	 d)de'de'de'de'deg e'f   f
dZ(	 d)de'de'de'de'deg e'f   f
dZ)	 	 	 d*de'dee'   dee'   dee'   de'f
dZ*de%fdZ+dedee'   fd Z, G d! d"e      Z- G d# d$e      Z.	 	 	 d*d%ee'   d&ee'   d'ee'   de.fd(Z/y)+    N)AnyCallableDictLiteral
NamedTupleOptionalUnioncast)AsyncAzureOpenAIAsyncOpenAIAzureOpenAIOpenAI)verbose_logger)	DualCache)BaseLLMException)BaseOpenAILLM)get_azure_ad_token_provider)get_secret_str)GenericLiteLLMParams)_add_path_to_api_basec            
            e Zd Z	 	 	 	 ddeej
                     deej                     deeej                  e	f      dee	   f fdZ
 xZS )AzureOpenAIErrorrequestresponseheadersbodyc                 0    t         |   ||||||       y )N)status_codemessager   r   r   r   )super__init__)selfr   r   r   r   r   r   	__class__s          p/Users/manta/Documents/Projects/TheRoad-I1/.venv/lib/python3.12/site-packages/litellm/llms/azure/common_utils.pyr!   zAzureOpenAIError.__init__   s)     	# 	 	
    )NNNN)__name__
__module____qualname__r   httpxRequestResponser	   Headersdictr!   __classcell__)r#   s   @r$   r   r      sl    
 ,0-18<#
 %--(	

 5>>*
 %t 345
 tn
 
r%   r   r   returnc                     i }d| v r| d   |d<   d| v r| d   |d<   d| v r| d   |d<   d| v r| d   |d<   | j                         D ci c]  \  }}dj                  d|      | }}}i ||S c c}}w )Nzx-ratelimit-limit-requestszx-ratelimit-remaining-requestszx-ratelimit-limit-tokenszx-ratelimit-remaining-tokensz{}-{}llm_provider)itemsformat)r   openai_headerskvllm_response_headerss        r$   process_azure_headersr8   +   s    N#w.7>(8
34 (72;B,<
78 "W,5<=W5X12%09@*:
56 :A9HA~q)1,   6"5n55	s   A,	tenant_id	client_idclient_secretscopec                    ddl m}m} t        j                  d       | j                  d      rt        |       }n| }|j                  d      rt        |      }n|}|j                  d      rt        |      }n|}t        j                  d|||       |||t        d       ||||      }	t        j                  d|	        ||	|      }
t        j                  d|
       |
S )	z
    Get Azure AD token provider from `client_id`, `client_secret`, and `tenant_id`

    Args:
        tenant_id: str
        client_id: str
        client_secret: str
        scope: str

    Returns:
        callable that returns a bearer token.
    r   )ClientSecretCredentialget_bearer_token_providerz$Getting Azure AD Token from Entra IDzos.environ/z,tenant_id %s, client_id %s, client_secret %sz8tenant_id, client_id, and client_secret must be providedcredential %stoken_provider %s)azure.identityr>   r?   r   debug
startswithr   
ValueError)r9   r:   r;   r<   r>   r?   
_tenant_id
_client_id_client_secret
credentialtoken_providers              r$    get_azure_ad_token_from_entra_idrK   B   s    $ Q?@M*#I.

M*#I.

.'6&6	 Z/>3ISTT'
JOJ*5.z5AN,n=r%   azure_usernameazure_passwordc                     ddl m}m} t        j                  d| ||        || ||      }t        j                  d|        |||      }t        j                  d|       |S )a  
    Get Azure AD token provider from `client_id`, `azure_username`, and `azure_password`

    Args:
        client_id: str
        azure_username: str
        azure_password: str
        scope: str

    Returns:
        callable that returns a bearer token.
    r   )UsernamePasswordCredentialr?   z2client_id %s, azure_username %s, azure_password %s)r:   usernamepasswordr@   rA   )rB   rO   r?   r   rC   )r:   rL   rM   r<   rO   r?   rI   rJ   s           r$   )get_azure_ad_token_from_username_passwordrR   z   sl    $ U<	 ,J *5.z5AN,n=r%   azure_ad_tokenazure_client_idazure_tenant_idc           	         |d}t        j                  dd      }|xs t        j                  d      }|xs t        j                  d      }||t        dd	      t        |       }|t        d
d	      t	        j
                  ||||d      }t        j                  |      }||S t        j                  }|j                  | d| d|d|d|d      }	|	j                  dk7  r!t        |	j                  |	j                  	      |	j	                         }
|
j                  dd      }|
j                  dd      }|t        dd	      |t        dd	      t        j                  |||       |S )z
    Get Azure AD token from OIDC token

    Args:
        azure_ad_token: str
        azure_client_id: Optional[str]
        azure_tenant_id: Optional[str]
        scope: str

    Returns:
        `azure_ad_token_access_token` - str
    N,https://cognitiveservices.azure.com/.defaultAZURE_AUTHORITY_HOSTz!https://login.microsoftonline.comAZURE_CLIENT_IDAZURE_TENANT_IDi  z/AZURE_CLIENT_ID and AZURE_TENANT_ID must be set)r   r   i  z6OIDC token could not be retrieved from secret manager.)rT   rU   azure_authority_host
oidc_token/z/oauth2/v2.0/tokenclient_credentialsz6urn:ietf:params:oauth:client-assertion-type:jwt-bearer)r:   
grant_typer<   client_assertion_typeclient_assertion)data   access_token
expires_inz(Azure AD Token access_token not returnedz&Azure AD Token expires_in not returned)keyvaluettl)osgetenvr   r   jsondumpsazure_ad_cache	get_cachelitellmmodule_level_clientpostr   textget	set_cache)rS   rT   rU   r<   r[   r\   azure_ad_token_cache_keyazure_ad_token_access_tokenclient	req_tokenazure_ad_token_jsonazure_ad_token_expires_ins               r$   get_azure_ad_token_from_oidcr{      s   $ }>99 C &E3D)EO%E3D)EO/"9E
 	

  /JL
 	

  $zz..$8$		
  #1":":;S"T".**((F
 /!22DE(.%] *
  	I #!--NN
 	

 $..*"5"9"9.$"O 3 7 7d K"*%O
 	
 !(%M
 	
 $)%   '&r%   azure_client_paramsc                 b    | j                  dd       }|d|v r|| d<   | j                  d       | S )Nazure_endpointz/openai/deploymentsbase_url)rs   pop)r|   r~   s     r$   !select_azure_base_url_or_endpointr     sC    (,,-=tDN! N2.<
+##$45r%   litellm_paramsc                 (   | j                  d      }| j                  d      xs t        d      }| j                  d      xs t        j                  d      }| j                  d      xs t        j                  d      }| j                  d      xs t        j                  d	      }| j                  d
      xs t        j                  d      }| j                  d      xs t        j                  d      }| j                  d      xs t        j                  dd      }|d}|*|r(|r&|r$t	        j
                  d       t        ||||      }|*|r(|r&|r$t	        j
                  d       t        ||||      }|r:|r8|r6|j                  d      r%t	        j
                  d       t        ||||      }nP|Nt        j                  du r<t	        j
                  d       	 t        |      }||t"        j%                  |      }|r`t'        |      rU	  |       }
t)        |
t               s8t	        j                  d t+        |
              t-        d!t+        |
             |
}	 |S |S # t        $ r t	        j
                  d       Y t        $ r)}	t	        j                  dt!        |	       d       |	d}	~	ww xY w# t,        $ r  t        $ r>}	t	        j                  dt!        |	              t/        d"t!        |	             |	d}	~	ww xY w)#a  
    Get Azure AD token from various authentication methods.

    This function tries different methods to obtain an Azure AD token:
    1. From an existing token provider
    2. From Entra ID using tenant_id, client_id, and client_secret
    3. From username and password
    4. From OIDC token
    5. From a service principal with secret workflow
    6. From DefaultAzureCredential

    Args:
        litellm_params: Dictionary containing authentication parameters
            - azure_ad_token_provider: Optional callable that returns a token
            - azure_ad_token: Optional existing token
            - tenant_id: Optional Azure tenant ID
            - client_id: Optional Azure client ID
            - client_secret: Optional Azure client secret
            - azure_username: Optional Azure username
            - azure_password: Optional Azure password

    Returns:
        Azure AD token as string if successful, None otherwise
    azure_ad_token_providerrS   AZURE_AD_TOKENr9   rZ   r:   rY   r;   AZURE_CLIENT_SECRETrL   AZURE_USERNAMErM   AZURE_PASSWORDazure_scopeAZURE_SCOPErW   N:Using Azure AD Token Provider from Entra ID for Azure Authr9   r:   r;   r<   0Using Azure Username and Password for Azure AuthrL   rM   r:   r<   oidc/%Using Azure OIDC Token for Azure AuthrS   rT   rU   r<   TzvUsing Azure AD token provider based on Service Principal with Secret workflow or DefaultAzureCredential for Azure Authr   *Azure AD Token Provider could not be used.z'Error calling Azure AD token provider: zm. Follow docs - https://docs.litellm.ai/docs/providers/azure/#azure-ad-token-refresh---defaultazurecredential)r<   z3Azure AD token provider returned non-string value: z%Azure AD token must be a string, got zFailed to get Azure AD token: )rs   r   ri   rj   r   rC   rK   rR   rD   r{   ro   enable_azure_ad_token_refreshr   rE   	ExceptionerrorstrBaseAzureLLM*_try_get_default_azure_credential_providercallable
isinstancetype	TypeErrorRuntimeError)r   r   rS   r9   r:   r;   rL   rM   r<   etokens              r$   get_azure_ad_tokenr     s3   : -001JK#''(89 ^>N "";/O299=N3OI"";/O299=N3OI"&&7 299<M $''(89XRYYGW=XN#''(89XRYYGW=XN}- E2E }> &9}H	
 #C'	#
 	 'OP"K))	#
 	%%g.DE5)%%	
 	 '11T9 E	
	&Ae&T# #*~/EGG H  $ 8,C#D	Q+-EeS)$$I$u+W  "GU} UVV!& >K  	O  !MN 	  9#a&  Bo  p G		8  	 	Q  #J3q6(!ST!?AxHIqP	Qs7   #I- AK -J>J>$J99J>L9LLc                   X   e Zd Zededeeg ef      fd       Z	 	 	 	 	 d!dee   dee   dee   deee	e
eef      d	ee   d
edee   deee	e
eef      fdZd	edee   dee   dee   dee   dedefdZ	 d"dededededeeej(                  f   d	edee   dee   deeg ef      dedeee	e
f      dee	e
f   fdZeded	ee   defd       Ze	 d"dee   d	eeeeeef   f      deed   ef   deeeed   f      def
d       Zedee   defd       Zd	eeef   dededee   fd Zy)#r   r<   r/   c                    ddl m} t        j                  d       	 t	        | |j
                        }t        j                  d       |S # t        $ r+}t        j                  dt        |              Y d}~yd}~ww xY w)z
        Try to get DefaultAzureCredential provider

        Args:
            scope: Azure scope for the token

        Returns:
            Token provider callable if DefaultAzureCredential is enabled and available, None otherwise
        r   )AzureCredentialTypez7Attempting to use DefaultAzureCredential for Azure Auth)r   azure_credentialzJSuccessfully obtained Azure AD token provider using DefaultAzureCredentialzDefaultAzureCredential failed: N)9litellm.types.secret_managers.get_azure_ad_token_providerr   r   rC   r   DefaultAzureCredentialr   r   )r<   r   r   r   s       r$   r   z7BaseAzureLLM._try_get_default_azure_credential_provider  s|    	
 	VW	&A!!4!K!K'#   \ +* 	  #B3q6(!KL	s   -A 	A?!A::A?Napi_keyapi_baseapi_versionrw   r   	_is_asyncmodelc                    d }t               }	||	d<   || j                  |	d      }
|
r"t        |
t        t        t
        t        f      r|
S | j                  |xs i |||||      }| j                  |      rr|j                  d      | dd}d|v r|d   |d<   d	|v r|d	   |d	<   d
|v r|d
   |d
<   t        j                  d|d           |du rt        di |}nxt        di |}nl|du rt	        di |}n\t        di |}nP|}|Lt        |t        t        f      r6t        |j                  t              r|j                  j                  d|       | j                  ||	d       |S )Nis_asyncazure)client_initialization_paramsclient_type)r   r   r   
model_namer   r   r   z/openai/v1/)r   r   timeoutmax_retrieshttp_clientz"Using Azure v1 API with base_url: r   Tapi-version)openai_clientr   r    )localsget_cached_openai_clientr   r   r   r   r   initialize_azure_sdk_client_is_azure_v1_api_versionrs   r   rC   _custom_queryr-   
setdefaultset_cached_openai_client)r"   r   r   r   rw   r   r   r   r   r   cached_clientr|   	v1_paramss                r$   get_azure_openai_clientz$BaseAzureLLM.get_azure_openai_client  s     	 .4X$3<$Z0> 99-I# : M !K1A6;#W )("&"B"B-3! '" #C # ,,[9  366yA#+*K 8	  33+>y+IIi( $77/B=/QIm, $77/B=/QIm,$$8:9N8OP $$/$<)$<M$*$7Y$7M $$4$K7J$KM$/$F2E$FM"M'}{<L.MN}::DA ++66}kR 	%%')E 	& 	

 r%   r   r   c                    |j                  d      }|j                  d      }| j                  |dd      }	| j                  |dd      }
| j                  |dd      }| j                  |d	d
      }| j                  |dd      }| j                  |dd      }|d}|j                  d      }|j                  d      }|s,|*|	r(|
r&|r$t        j                  d       t	        |	|
||      }|*|r(|r&|
r$t        j                  d       t        |||
|      }|6|j                  d      r%t        j                  d       t        ||
|	|      }n8|s6|4t        j                  du r"t        j                  d       	 t        |      }|$t        j                  dt        j                        }|}|t        |t               r|d d dz   }t        j                  d | d!t!        |       d"|        |||||d#}|du r| j#                         |d$<   n| j%                         |d$<   |||d<   |||d<   |||d<   t'        |%      }|S # t        $ r t        j                  d       Y w xY w)&Nr   rS   r9   rZ   r:   rY   r;   r   rL   r   rM   r   r   r   rW   r   r   r   r   r   r   r   r   r   Tz\Using Azure AD token provider based on Service Principal with Secret workflow for Azure Authr   r   AZURE_API_VERSION   z***************z%Initializing Azure OpenAI Client for z, Api Base: z
, Api Key:)r   r~   r   rS   r   r   )r|   )rs   _resolve_env_varr   rC   rK   rR   rD   r{   ro   r   r   rE   ri   rj   AZURE_DEFAULT_API_VERSIONr   r   _get_async_http_client_get_sync_http_clientr   )r"   r   r   r   r   r   r   r   rS   r9   r:   r;   rL   rM   r<   r   r   _api_keyr|   s                      r$   r   z(BaseAzureLLM.initialize_azure_sdk_client  s    #1"4"45N"O'++,<= ))K):
	 ))K):
	 --O-B
 ..,.>
 ..,.>
 %%nm]S=BE$((7 $$Y/'/  L 'G##+	'# $+  !ST&O--#	'# %.*C*CG*L  !HI9- ) )	N '/55=  nS*E %+'
 ))#W%F%FK Jx$=|h.H3J<|CPXM?Zdemdno	
 &&,'>
 t151L1L1N.151K1K1M."1<.-4	*".=T 9: @ 3
 #"S  S$$%QRSs   9I I%$I%r   r   rS   r   acompletionc                    |j                  dt        j                  d            }|j                  dt        j                  d            }|j                  dt        j                  dd            }||j                  d      s|dz  }|| z  }|| t        j
                  ||d	}|||d
<   n'|%|j                  d      rt        ||||      }||d<   |	|	|d<   |
du rt        di |}|S t        di |}|S )Nr9   rZ   r:   rY   r   r   rW   r]   )r   r   r   r   r   r   r   r   rS   r   Tr   )
rs   ri   rj   endswithro   client_sessionrD   r{   r   r   )r"   r   r   r   r   r   r   r   rS   r   r   rw   r9   r:   r<   r|   s                   r$   ,_init_azure_client_for_cloudflare_ai_gatewayz9BaseAzureLLM._init_azure_client_for_cloudflare_ai_gateway  s9    #&&{BII>O4PQ	"&&{BII>O4PQ	""IIm%ST
 >$$S)C5'"H  +'j&55*"3 "18#I.+!,,W5%A'5(1(1#	&N 9G#$45&2AX#$=>d")@,?@  %;':;r%   r   c                     |xs
 t               }d| v r| S |j                  xs< t        j                  xs* t        j                  xs t	        d      xs t	        d      }|r|| d<   | S t        |      }|rd| | d<   | S )Nzapi-keyAZURE_OPENAI_API_KEYAZURE_API_KEYzBearer Authorization)r   r   ro   	azure_keyr   r   )r   r   r   rS   s       r$    _base_validate_azure_environmentz-BaseAzureLLM._base_validate_azure_environment  s     (A+?+A N "" //  / 45/ o. 	 !(GIN ,N;)00@'AGO$r%   route)z/openai/responsesz/openai/vector_storesdefault_api_version)latestpreviewc                 ~   | xs t         j                  xs t        d      } | t        d|  d      t	        j
                  |       }|xs i }t        t        t           |j                  d            xs |}t        |j                        }d|vr|r||d<   || vrt        | |      }n| }t        j                  |      rNd|vrJt	        j
                  |      }t        |j                  |j                   j#                  dd      	            }t	        j
                  |      j                  |
      }	t        |	      S )a}  
        Get the base Azure URL for the given route and API version.

        Args:
            api_base: The base URL of the Azure API.
            litellm_params: The litellm parameters.
            route: The route to the API.
            default_api_version: The default API version to use if no api_version is provided. If 'latest', it will use `openai/v1/...` route.
        AZURE_API_BASEz^api_base is required for Azure AI Studio. Please set the api_base parameter. Passed `api_base=`r   r   )r   ending_pathz
/openai/v1z/openai)path)params)ro   r   r   rE   r)   URLr
   r   r   rs   r-   r   r   r   r   	copy_withr   replace)
r   r   r   r   original_urlr   query_paramsnew_url
parsed_url	final_urls
             r$   _get_base_azure_urlz BaseAzureLLM._get_base_azure_url  sC   " Sw//S>BR3Spqypzz{|  yy* (-2# 2 2= AB #" 	 L//0 ,*5L'  +X5QGG00=7*"YYw/
(('__44YM )  IIg&000E	9~r%   c                     | y| dv S )NF>   v1r   r   r   )r   s    r$   r   z%BaseAzureLLM._is_azure_v1_api_version  s    999r%   	param_keyenv_var_keyc                 V    |j                  |      }||S t        j                  |      S )a!  Resolve the environment variable for a given parameter key.

        The logic here is different from `params.get(key, os.getenv(env_var))` because
        litellm_params may contain the key with a None value, in which case we want
        to fallback to the environment variable.
        )rs   ri   rj   )r"   r   r   r   param_values        r$   r   zBaseAzureLLM._resolve_env_var"  s/     %((3"yy%%r%   )NNNFN)N)r&   r'   r(   staticmethodr   r   r   r   r	   r   r   r   r   r-   boolr   r   intfloatr)   Timeoutr   r   r   r   r   r   r   r   r   r   r%   r$   r   r     s   	(2s7#	$ F &* )-#S#S 3-S c]	S
 +/DE
S !S S }S 
%%5v{JK	LSj## ## 3-	#
 SM# c]# # 
#Z BF44 4 	4
 4 uemm+,4 4 #4 !4 "*(2s7*;!<4 4 {,<<=>4 
{,,	-4l '/0D'E	 : 
 SW	83-8 ';T#s(^'K!LM8 WIJCOP8 &eC9L1M,M&NO	8
 
8 8t :hsm : : :
&"38n&9<&KN&	#&r%   r   c                   >    e Zd ZU ee   ed<   ee   ed<   ee   ed<   y)AzureCredentialsr   r   r   N)r&   r'   r(   r   r   __annotations__r   r%   r$   r   r   1  s     smc]#r%   r   r   r   r   c                 "   | xs t         j                  xs t        d      }|xs t         j                  xs t        d      }|xs< t         j                  xs* t         j
                  xs t        d      xs t        d      }t        |||      S )zEResolve Azure credentials from params, litellm globals, and env vars.r   r   r   r   )r   r   r   )ro   r   r   r   r   r   r   )r   r   r   resolved_api_baseresolved_api_versionresolved_api_keys         r$   get_azure_credentialsr   7  s     !XG$4$4XGW8XQw**Qn=P.Q  	 	+??	+	+ 01	+ /*  " ( r%   )rW   )NNN)0rk   ri   typingr   r   r   r   r   r   r	   r
   r)   openair   r   r   r   ro   litellm._loggingr   litellm.caching.cachingr   )litellm.llms.base_llm.chat.transformationr    litellm.llms.openai.common_utilsr   3litellm.secret_managers.get_azure_ad_token_providerr   litellm.secret_managers.mainr   litellm.types.routerr   litellm.utilsr   rm   r   r,   r-   r8   r   rK   rR   r{   r   r   r   r   r   r   r%   r$   <module>r     s    	 R R R  E E  + - F : 8 5 /
' 
(65)<#= 6$ 66 @	555 5 	5
 b#g5x @	&&& & 	&
 b#g&V &*%)	['['c][' c][' C=	['
 	['|	4 	F(Fc]FRX&= X&vz  #!!%smc] # 	r%   