o
    ưiy                     @   s  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 deZ#de	ej$e%f de%fddZ&	d1de'de'de'de'deg e'f f
ddZ(	d1de'de'de'de'deg e'f f
ddZ)			d2de'dee' dee' dee' de'f
d d!Z*d"e%fd#d$Z+d%edee' fd&d'Z,G d(d) d)eZ-G d*d+ d+eZ.			d2d,ee' d-ee' d.ee' de.fd/d0Z/dS )3    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                
       sV   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dZ
  ZS )	AzureOpenAIErrorNrequestresponseheadersbodyc                    s   t  j||||||d d S )N)status_codemessager   r   r   r   )super__init__)selfr   r   r   r   r   r   	__class__ V/home/app/Keep/.python/lib/python3.10/site-packages/litellm/llms/azure/common_utils.pyr      s   	
zAzureOpenAIError.__init__)NNNN)__name__
__module____qualname__r   httpxRequestResponser   Headersdictr   __classcell__r"   r"   r    r#   r      s    r   r   returnc                 C   sr   i }d| v r| d |d< d| v r| d |d< d| v r | d |d< d| v r*| d |d< dd |   D }i ||S )Nzx-ratelimit-limit-requestszx-ratelimit-remaining-requestszx-ratelimit-limit-tokenszx-ratelimit-remaining-tokensc                 S   s   i | ]\}}d  d||qS )z{}-{}Zllm_provider)format).0kvr"   r"   r#   
<dictcomp>;   s    z)process_azure_headers.<locals>.<dictcomp>)items)r   Zopenai_headersZllm_response_headersr"   r"   r#   process_azure_headers+   s&   r4   ,https://cognitiveservices.azure.com/.default	tenant_id	client_idclient_secretscopec                 C   s   ddl m}m} td | drt| }n| }|dr#t|}n|}|dr/t|}n|}td||| |du sE|du sE|du rItd||||}	td|	 ||	|}
t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 %sNz8tenant_id, client_id, and client_secret must be providedcredential %stoken_provider %s)azure.identityr:   r;   r   debug
startswithr   
ValueError)r6   r7   r8   r9   r:   r;   Z
_tenant_idZ
_client_idZ_client_secret
credentialtoken_providerr"   r"   r#    get_azure_ad_token_from_entra_idB   s0   







rD   azure_usernameazure_passwordc                 C   sT   ddl m}m} td| || || ||d}td| |||}t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)r7   usernamepasswordr<   r=   )r>   rG   r;   r   r?   )r7   rE   rF   r9   rG   r;   rB   rC   r"   r"   r#   )get_azure_ad_token_from_username_passwordz   s    
rJ   azure_ad_tokenazure_client_idazure_tenant_idc                 C   s8  |du rd}t dd}|pt d}|pt d}|du s"|du r(tddd	t| }|du r6td
dd	t||||d}t|}|durK|S tj	}|j
| d| d|d|d|dd}	|	jdkrnt|	j|	jd	|	 }
|
dd}|
dd}|du rtddd	|du rtddd	tj|||d |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
    Nr5   Z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.)rL   rM   azure_authority_host
oidc_token/z/oauth2/v2.0/tokenZclient_credentialsz6urn:ietf:params:oauth:client-assertion-type:jwt-bearer)r7   Z
grant_typer9   Zclient_assertion_typeZclient_assertion)data   Zaccess_tokenZ
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_cacheZ	get_cachelitellmZmodule_level_clientpostr   textgetZ	set_cache)rK   rL   rM   r9   rP   rQ   Zazure_ad_token_cache_keyZazure_ad_token_access_tokenclientZ	req_tokenZazure_ad_token_jsonZazure_ad_token_expires_inr"   r"   r#   get_azure_ad_token_from_oidc   sx   
	
rb   azure_client_paramsc                 C   s2   |  dd }|d urd|v r|| d< | d | S )Nazure_endpointz/openai/deploymentsbase_url)r`   pop)rc   rd   r"   r"   r#   !select_azure_base_url_or_endpoint  s   
rg   litellm_paramsc              
   C   sn  |  d}|  dptd}|  dptd}|  dp!td}|  dp+td	}|  d
p5td}|  dp?td}|  dpJtdd}|du rQd}|du rh|rh|rh|rhtd t||||d}|du r|r|r|rtd t||||d}|r|r|r|drtd t	||||d}nJ|du rt
jdu rtd zt|d}W n& ty   td Y n ty }	 ztdt|	 d |	d}	~	ww |du r|du rtj|d}|r5t|r5z!| }
t|
tstd t|
  td!t|
 |
}W |S  ty     ty4 }	 ztdt|	  td"t|	 |	d}	~	ww |S )#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_providerrK   ZAZURE_AD_TOKENr6   rO   r7   rN   r8   AZURE_CLIENT_SECRETrE   AZURE_USERNAMErF   AZURE_PASSWORDazure_scopeAZURE_SCOPEr5   N:Using Azure AD Token Provider from Entra ID for Azure Authr6   r7   r8   r9   0Using Azure Username and Password for Azure AuthrE   rF   r7   r9   oidc/%Using Azure OIDC Token for Azure AuthrK   rL   rM   r9   TzvUsing Azure AD token provider based on Service Principal with Secret workflow or DefaultAzureCredential for Azure Authrm   *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)r9   z3Azure AD token provider returned non-string value: z%Azure AD token must be a string, got zFailed to get Azure AD token: )r`   r   rX   rY   r   r?   rD   rJ   r@   rb   r]   enable_azure_ad_token_refreshr   rA   	ExceptionerrorstrBaseAzureLLM*_try_get_default_azure_credential_providercallable
isinstancetype	TypeErrorRuntimeError)rh   ri   rK   r6   r7   r8   rE   rF   r9   etokenr"   r"   r#   get_azure_ad_token  s   
	
	


r   c                   @   s  e Zd Zededeeg ef  fd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dZdedee dee dee d	ee dedefd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dZededee defd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"d#Zed	ee defd$d%Zdeeef d&ed'edee fd(d)ZdS ),r|   r9   r-   c              
   C   sp   ddl m} td zt| |jd}td |W S  ty7 } ztdt|  W Y d}~dS d}~w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)rm   Zazure_credentialzJSuccessfully obtained Azure AD token provider using DefaultAzureCredentialzDefaultAzureCredential failed: N)Z9litellm.types.secret_managers.get_azure_ad_token_providerr   r   r?   r   ZDefaultAzureCredentialry   r{   )r9   r   ri   r   r"   r"   r#   r}     s    
z7BaseAzureLLM._try_get_default_azure_credential_providerNFapi_keyapi_baseapi_versionra   rh   	_is_asyncmodelc                 C   sd  d }t  }	||	d< |d u r| j|	dd}
|
r!t|
ttttfr!|
S | j|p&i |||||d}| |rz|	d| dd}d|v rH|d |d< d	|v rR|d	 |d	< d
|v r\|d
 |d
< t
d|d   |du rrtdi |}n6tdi |}n.|du rtdi |}n"tdi |}n|}|d urt|ttfrt|jtr|jd| | j||	dd |S )Nis_asyncZazure)client_initialization_paramsclient_type)rh   r   r   
model_namer   r   r   z/openai/v1/)r   re   timeoutmax_retrieshttp_clientz"Using Azure v1 API with base_url: re   Tapi-version)openai_clientr   r   r"   )localsZget_cached_openai_clientr   r   r
   r   r   initialize_azure_sdk_client_is_azure_v1_api_versionr`   r   r?   Z_custom_queryr+   
setdefaultZset_cached_openai_client)r   r   r   r   ra   rh   r   r   r   r   Zcached_clientrc   Z	v1_paramsr"   r"   r#   get_azure_openai_client  sb   



z$BaseAzureLLM.get_azure_openai_clientr   r   c                 C   s4  | d}| d}| |dd}	| |dd}
| |dd}| |d	d
}| |dd}| |dd}|d u r:d}| d}| d}|s]|d u r]|	r]|
r]|r]td t|	|
||d}|d u rt|rt|rt|
rttd t|||
|d}|d ur|drtd t||
|	|d}n&|s|d u rtj	du rtd zt
|d}W n ty   td Y nw |d u rtdtj}|}|d urt|tr|d d d }td | d!t| d"|  |||||d#}|du r|  |d$< n|  |d$< |d ur||d< |d ur
||d< |d ur||d< t|d%}|S )&Nri   rK   r6   rO   r7   rN   r8   rj   rE   rk   rF   rl   rm   rn   r5   r   r   ro   rp   rq   rr   rs   rt   ru   Tz\Using Azure AD token provider based on Service Principal with Secret workflow for Azure Authrv   rw   AZURE_API_VERSION   z***************z%Initializing Azure OpenAI Client for z, Api Base: z
, Api Key:)r   rd   r   rK   ri   r   )rc   )r`   _resolve_env_varr   r?   rD   rJ   r@   rb   r]   rx   r   rA   rX   rY   ZAZURE_DEFAULT_API_VERSIONr   r{   Z_get_async_http_clientZ_get_sync_http_clientrg   )r   rh   r   r   r   r   r   ri   rK   r6   r7   r8   rE   rF   r9   r   r   Z_api_keyrc   r"   r"   r#   r      s   
	









z(BaseAzureLLM.initialize_azure_sdk_clientr   r   rK   ri   acompletionc                 C   s   | dtd}| dtd}| dtdd}|d u rr|ds)|d7 }|| 7 }|| tj||d	}|d urA||d
< n|d urV|drRt||||d}||d< |	d ur^|	|d< |
du rktdi |}|S t	di |}|S )Nr6   rO   r7   rN   rm   rn   r5   rR   )r   re   r   r   r   r   rs   ru   rK   ri   Tr"   )
r`   rX   rY   endswithr]   Zclient_sessionr@   rb   r
   r   )r   r   r   r   r   r   rh   r   rK   ri   r   ra   r6   r7   r9   rc   r"   r"   r#   ,_init_azure_client_for_cloudflare_ai_gatewayw  sD   




z9BaseAzureLLM._init_azure_client_for_cloudflare_ai_gatewayr   c                 C   sf   |pt  }d| v r| S |jptjptjptdptd}|r$|| d< | S t|}|r1d| | d< | S )Nzapi-keyAZURE_OPENAI_API_KEYAZURE_API_KEYzBearer Authorization)r   r   r]   	azure_keyr   r   )r   rh   r   rK   r"   r"   r#    _base_validate_azure_environment  s&   
z-BaseAzureLLM._base_validate_azure_environmentroute)z/openai/responsesz/openai/vector_storesdefault_api_version)latestpreviewc           
      C   s   | pt jptd} | du rtd|  dt| }|pi }ttt |	dp)|}t
|j}d|vr9|r9||d< || vrDt| |d}n| }t|rad|vrat|}t|j|jd	dd
}t|j|d}	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_BASENz^api_base is required for Azure AI Studio. Please set the api_base parameter. Passed `api_base=`r   r   )r   Zending_pathz
/openai/v1z/openai)path)params)r]   r   r   rA   r'   URLr	   r   r{   r`   r+   r   r   r|   r   	copy_withr   replace)
r   rh   r   r   original_urlr   Zquery_paramsnew_url
parsed_urlZ	final_urlr"   r"   r#   _get_base_azure_url  s4   




z BaseAzureLLM._get_base_azure_urlc                 C   s   | d u rdS | dv S )NF>   r   v1r   r"   )r   r"   r"   r#   r     s   z%BaseAzureLLM._is_azure_v1_api_version	param_keyenv_var_keyc                 C   s    | |}|dur|S t|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.
        N)r`   rX   rY   )r   rh   r   r   Zparam_valuer"   r"   r#   r     s   

zBaseAzureLLM._resolve_env_var)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    #	
K
 	


6:*r|   c                   @   s2   e Zd ZU ee ed< ee ed< ee ed< dS )AzureCredentialsr   r   r   N)r$   r%   r&   r   r{   __annotations__r"   r"   r"   r#   r     s   
 r   r   r   r   c                 C   sR   | pt jptd}|pt jptd}|p!t jp!t jp!tdp!td}t|||dS )zEResolve Azure credentials from params, litellm globals, and env vars.r   r   r   r   )r   r   r   )r]   r   r   r   r   r   r   )r   r   r   Zresolved_api_baseZresolved_api_versionZresolved_api_keyr"   r"   r#   get_azure_credentials  s0   r   )r5   )NNN)0rZ   rX   typingr   r   r   r   r   r   r   r	   r'   Zopenair
   r   r   r   r]   Zlitellm._loggingr   Zlitellm.caching.cachingr   Z)litellm.llms.base_llm.chat.transformationr   Z litellm.llms.openai.common_utilsr   Z3litellm.secret_managers.get_azure_ad_token_providerr   Zlitellm.secret_managers.mainr   Zlitellm.types.routerr   Zlitellm.utilsr   r\   r   r*   r+   r4   r{   rD   rJ   rb   rg   r   r|   r   r   r"   r"   r"   r#   <module>   s    (

<

+
^
    