
    gn                        d dl Z d dlZd dlZd dlmZmZmZmZmZ d dl	m
Z
 d dlmZ d dlZd dlmZmZ d dlmZ d dlmZmZmZmZmZmZ d dlmZ d d	lmZmZ  e       Zer	d d
l m!Z" e"Z!neZ!d Z#de
de$fdZ%de&de
fdZ'dedee   defdZ(dede!dee   fdZ)	 d&dedee$   de&fdZ* G d d      Z+	 	 d'de&de
dede!deee$ef      dee$   fdZ,dee&   dedee-   fdZ.de&dee&   ded e/de/f
d!Z0de&d"e$defd#Z1de&de&fd$Z2de&de
fd%Z3y)(    N)TYPE_CHECKINGAnyDictOptionalUnion)Request)Headers)verbose_loggerverbose_proxy_logger)ServiceLogging)AddTeamCallbackCommonProxyErrorsLitellmDataForBackendLLMCallSpecialHeadersTeamCallbackMetadataUserAPIKeyAuth)ServiceTypes)!StandardLoggingUserAPIKeyMetadataSupportedCacheControls)ProxyConfigc                     i }| j                  d      }|D ]%  }d|v r|j                  d      \  }}|||<   !d||<   ' |S )Nz, =T)split)cache_control
cache_dict
directives	directivekeyvalues         Y/var/www/openai/venv/lib/python3.12/site-packages/litellm/proxy/litellm_pre_call_utils.pyparse_cache_controlr!   %   sV    J$$T*J	)"-JC#JsO$(Jy!       requestreturnc                     d| j                   j                  v sd| j                   j                  v ryd| j                   j                  v ryd| j                   j                  v ryy)z
    Helper to return what the "metadata" field should be called in the request data

    For all /thread or /assistant endpoints we need to call this "litellm_metadata"

    For ALL other endpoints we call this "metadata
    thread	assistantlitellm_metadatabatchesz/v1/messagesmetadata)urlpathr#   s    r    _get_metadata_variable_namer.   3   sW     7;;###{gkk6F6F'F!GKK$$$!)))!r"   datac                     	 t        |d      r#t        |j                        }d|v r	|d   | d<   y y y # t        $ r Y y t        $ r)}t        j                  dt        |             Y d }~y d }~ww xY w)Nquery_paramsapi-versionapi_versionz.error checking api version in query params: %s)hasattrdictr1   KeyError	Exceptionr
   	exceptionstr)r/   r#   r1   es       r    &safe_add_api_version_from_query_paramsr;   F   s{    

7N+ 4 45L,&2=&A]# - ,   
  <c!f	
 	

s   -2 	A.A.A))A.team_callback_settings_objc                    |
t               }| j                  dk(  rS|j                  g |_        | j                  |j                  vr6|j                  j	                  | j                         n| j                  dk(  rQ|j
                  g |_        | j                  |j
                  vr|j
                  j	                  | j                         n| j                  dk(  r|j                  g |_        |j
                  g |_        | j                  |j                  vr%|j                  j	                  | j                         | j                  |j
                  vr%|j
                  j	                  | j                         | j                  j                         D ]S  \  }}|j                  i |_        t        t        j                  j                  ||      xs |      |j                  |<   U |S )Nsuccessfailuresuccess_and_failure)default_value)r   callback_typesuccess_callbackcallback_nameappendfailure_callbackcallback_varsitemsr9   litellmutils
get_secret)r/   r<   varr   s       r    (convert_key_logging_metadata_to_callbackrM   T   s    ")%9%;"Y&%66>:<&7%?%P%PP&77>>t?Q?QR			y	(%66>:<&7%?%P%PP&77>>t?Q?QR			4	4%66>:<&7%66>:<&7%?%P%PP&77>>t?Q?QR%?%P%PP&77>>t?Q?QR((..0
U%33;79&48;MM$$U%$@IE9
"005 1 &%r"   user_api_key_dictproxy_configc                    d }| j                   :d| j                   v r,| j                   d   D ]  }t        t        di ||      } |S | j                  Td| j                  v rF	 | j                  }|j	                  dd       xs i }t        di |}t        j                  d|       |S | j                  !t        j                  | j                  |      }|S )Nlogging)r/   r<   callback_settingsz$Team callback settings activated: %s)team_idrO    )r*   rM   r   team_metadatagetr   r   debugrS   LiteLLMProxyRequestSetup$add_team_based_callbacks_from_config)rN   rO   callback_settings_objitemrU   rR   s         r    _get_dynamic_logging_metadatar\   {   s	    =A"".*333%..y9D$L$,t,+@%! :< ! 1 	''3#4#B#BB	 *77)--.A4HNB 4 I7H I""24I	
 !  
	"	"	.$II)11 J  	
 ! r"   headerslitellm_key_header_namec                 @   t         j                  j                         D cg c]  }|j                  j	                          }}|}||j                  |j	                                i }| j                         D ]  \  }}|j	                         |vs|||<    |S c c}w )z.
    Removes litellm api key from headers
    )r   _member_map_valuesr   lowerrE   rH   )r]   r^   vspecial_headersclean_headersheaderr   s          r    re   re      s     1?0K0K0R0R0TU0T1qww}}0TOU%O*6<<>?M <<>0$)M&! )  Vs   !Bc                   6   e Zd Zedeeef   fd       Ze	 ddedee	   dee
   fd       Zedededefd       Zedd	dededee	e
ef      defd
       Zededefd       Zededede
fd       Zedee   dee   defd       Zede
dedee   fd       Zy)rX   r]   c                     i }| j                         D ]J  \  }}|j                         j                  d      s&|j                         j                  d      rF|||<   L |S )z
        Get the headers that should be forwarded to the LLM Provider.

        Looks for any `x-` headers and sends them to the LLM Provider.
        zx-zx-stainless)rH   rb   
startswith)r]   forwarded_headersrf   r   s       r    _get_forwardable_headersz1LiteLLMProxyRequestSetup._get_forwardable_headers   s]     $]]_MFE||~((.v||~7P7P8 -2!&)	 - ! r"   Ngeneral_settingsr$   c                     ||j                  d      dury| j                         D ]  \  }}|j                         dk(  s|c S  y)z9
        Get the OpenAI Org ID from the headers.
        Nforward_openai_org_idTzopenai-organization)rV   rH   rb   )r]   rl   rf   r   s       r    get_openai_org_id_from_headersz7LiteLLMProxyRequestSetup.get_openai_org_id_from_headers   sN     ( $$%<=TI$]]_MFE||~!66 - r"   rN   c                     t         j                  |       }t        j                  du rEt         j	                  |      }|j                         D ]  \  }}|	||dj                  |      <    |S )z
        Add headers to the LLM call

        - Checks request headers for forwardable headers
        - Checks if user information should be added to the headers
        TrN   zx-litellm-{})rX   rk   rI   #add_user_information_to_llm_headers'get_sanitized_user_information_from_keyrH   format)r]   rN   returned_headers litellm_logging_metadata_headerskrc   s         r    add_headers_to_llm_callz0LiteLLMProxyRequestSetup.add_headers_to_llm_call   s|     4LLWU66$>(PP&7 Q  -
 9>>@1=AB$^%:%:1%=> A  r"   )rl   c                     t               }|r3|j                  d      du r t        j                  | |      }|i k7  r||d<   t        j	                  | |      }|||d<   |S )zB
        - Adds forwardable headers
        - Adds org id
        !forward_client_headers_to_llm_apiTr]   organization)r   rV   rX   rx   ro   )r]   rN   rl   r/   _headers_organizations         r    %add_litellm_data_for_backend_llm_callz>LiteLLMProxyRequestSetup.add_litellm_data_for_backend_llm_call   sx     ,- $$%HITQ/GG*H 2~"*Y0OO%
 $#0D r"   c           	          t        | j                  | j                  | j                  | j                  | j
                  | j                  | j                        }|S )N)user_api_key_hashuser_api_key_aliasuser_api_key_team_iduser_api_key_user_iduser_api_key_org_iduser_api_key_team_aliasuser_api_key_end_user_id)r   api_key	key_aliasrS   user_idorg_id
team_aliasend_user_id)rN   user_api_key_logged_metadatas     r    rs   z@LiteLLMProxyRequestSetup.get_sanitized_user_information_from_key  sW     (I/770::!2!:!:!2!:!: 1 8 8$5$@$@%6%B%B(
$ ,+r"   key_metadatar/   _metadata_variable_namec                 ,   d| v rDi |d<   t        | d   t              r,| d   j                         D ]  \  }}|t        v s||d   |<    d| v r7| d   2t        j                  ||   j                  d      | d         ||   d<   d| v rmt        | d   t              rZd||   v rHt        ||   d   t              r2| d   j                         D ]  \  }}|||   d   vs|||   d   |<    n| d   ||   d<   d| v rt        | d   t              r| d   |d<   |S )Ncachetagsrequest_tagstags_to_addspend_logs_metadatadisable_fallbacks)
isinstancer5   rH   r   rX   _merge_tagsrV   bool)r   r/   r   rw   rc   r   r   s          r    add_key_level_controlsz/LiteLLMProxyRequestSetup.add_key_level_controls  s    l"DM,w/6(1779DAq22+,Wa( :
 \!l6&:&F(44!%&=!>!B!B6!J ,V 4 5  ()&1 !L0Z./6
 %-D(EE*,-.CDdK #//D"E"K"K"MJC4(?#@AV#WW " 456KL	 #N HT)H,-.CD
 ,.:,-t4
 )55H(ID$%r"   r   r   c                     g }| r!t        | t              r|j                  |        |r-t        |t              r|D ]  }||vs|j                  |        |S )a5  
        Helper function to merge two lists of tags, ensuring no duplicates.

        Args:
            request_tags (Optional[list]): List of tags from the original request
            tags_to_add (Optional[list]): List of tags to add

        Returns:
            list: Combined list of unique tags
        )r   listextendrE   )r   r   
final_tagstags       r    r   z$LiteLLMProxyRequestSetup._merge_tagsI  sW     
J|T:l+:k48"j(%%c* # r"   rS   rO   c                 P   |j                  |       }t        |j                               dk(  ryi |j                  d|      }|j	                  dd       |j	                  dd       |j	                  dd       t        |j                  dd      |j                  dd      |      S )	z:
        Add team-based callbacks from the config
        )rS   r   NrG   rS   rC   rF   )rC   rF   rG   )load_team_configlenkeysrV   popr   )rS   rO   team_configcallback_vars_dicts       r    rY   z=LiteLLMProxyRequestSetup.add_team_based_callbacks_from_configa  s     #33G3D{!"a'N MNy$/148148#(__-?F(__-?F,
 	
r"   N)__name__
__module____qualname__staticmethodr   r	   r5   rk   r   r   r9   ro   r   rx   r   r   r~   r   rs   r   r   r   r   r   rY   rT   r"   r    rX   rX      s   !w}%! !" :>)1$	#     *8 	   0 
 6:	 * #4S>2	
 
& 6 ,),	*, , ))"&)AD) )V (4. x~ RV  . 

!
 
&	'
 
r"   rX   rl   versionc           
      (  K   ddl m}m} t        | |       t	        |j
                  ||j                  d      nd      }| j                  t        j                  |||             t        |j                        |j                  |t        j                  |       d| d<   	 |j                  }	t        |	      }
|
j                  d	      }||| d
<   t#        | |       |j
                  }t%        j&                  d|       |j                  dd      }|rt)        |      }|j                  d      | d<   t%        j&                  d|        t+        |      }|| vri | |<   d| v r#| d   t        j,                  | d         | |   d<   t        j/                  |      }| |   j                  |       |j0                  | |   d<   t3        |dd      | |   d<   || |   d<   ||j                  dd      | |   d<   |j4                  }t        j7                  || |      } |j8                  xs i }d|v r7|d   2t        j;                  | |   j                  d      |d         | |   d<   d|v rmt=        |d   t              rZd| |   v rHt=        | |   d   t              r2|d   j?                         D ]  \  }}|| |   d   vs|| |   d   |<    n|d   | |   d<   |j@                  | |   d<   |jB                  | |   d<   |jD                  | |   d<   |jF                  | |   d <   |jH                  | |   d!<   |j4                  | |   d"<   t        |j
                        }|jK                  d#d       || |   d$<   t        |j                        | |   d%<   |jL                  | |   d&<   tO        | |'       |jP                  |jP                  | d(<   tS        jR                         }d)}|d*u r|?|j                  d+      d*u r,|*tU        |d$      rd,|j
                  v r|j
                  d,   }nF|DtU        |d-      r8tU        |jV                  d.      r"|jV                  |jV                  jX                  }|| |   d/<   |r|jZ                  d*u rd| v r| d   | |   d<   t]        ||0      }|Q|j^                  | d1<   |j`                  | d2<   |jb                  '|jb                  j?                         D ]
  \  }}|| |<    te        | ||3       t%        j&                  d4|        tg        | |||5       tS        jR                         }ti        jj                  tl        jo                  tp        jr                  ||z
  d6|||jL                  7             | S # t         $ r i }
Y w xY ww)8a  
    Adds LiteLLM-specific data to the request.

    Args:
        data (dict): The data dictionary to be modified.
        request (Request): The incoming request.
        user_api_key_dict (UserAPIKeyAuth): The user API key dictionary.
        general_settings (Optional[Dict[str, Any]], optional): General settings. Defaults to None.
        version (Optional[str], optional): Version. Defaults to None.

    Returns:
        dict: The modified data dictionary.

    r   )
llm_routerpremium_userNr^   )r^   )r]   rN   rl   )r+   methodr]   bodyproxy_server_requestr2   r3   )r/   r]   zRequest Headers: %szCache-Controlzs-maxagettlzreceiving data: %sr*   requester_metadatarq   user_api_keyend_user_max_budgetuser_api_end_user_max_budgetlitellm_api_versionglobal_max_parallel_requests)r   r/   r   r   r   r   user_api_key_team_max_budgetuser_api_key_team_spenduser_api_key_spenduser_api_key_max_budgetuser_api_key_model_max_budgetuser_api_key_metadataauthorizationr]   endpointlitellm_parent_otel_spanr-   allowed_model_region Tuse_x_forwarded_forzx-forwarded-forclienthostrequester_ip_address)rN   rO   rC   rF   )r/   r   rN   z5[PROXY] returned data from litellm_pre_call_utils: %s)request_bodyrl   rN   r   add_litellm_data_to_request)serviceduration	call_type
start_timeend_timeparent_otel_span):litellm.proxy.proxy_serverr   r   r;   re   r]   rV   updaterX   r~   r9   r+   r   copyr1   r5   r6   (add_provider_specific_headers_to_requestr   rW   r!   r.   deepcopyrs   r   getattrr*   r   rU   r   r   rH   team_max_budget
team_spendspend
max_budgetmodel_max_budgetr   r   _add_otel_traceparent_to_datar   timer4   r   r   enable_tag_filteringr\   rC   rF   rG   move_guardrails_to_metadata_enforced_params_checkasynciocreate_taskservice_logger_objasync_service_success_hookr   PROXY_PRE_CALL)r/   r#   rN   rO   rl   r   r   r   r|   r1   
query_dictdynamic_api_versionr]   cache_control_headerr   r   r   r   rU   r   r   r   r   rZ   rw   rc   r   s                              r    r   r   y  s    , D*49  +   !:;H 	KK FF/- 	G 	
 7;;..		$	$D	 ++,'

 *4)F&1] -$I ooG4g>";;=()=>
 nnZ0U3T:9'Bd*(*$% Td:.:>Bmm?
$%&:;
 	!HH/ 	I 	
 !
 		 !(()EF 	!! 		 ! EL0$ED	 !"@A <CD	 !"78#  !?F 	$%&DE
 %--L#::! 7 ; D &339rM=#8#D0H0T0T56::6B%f- 1U 1
$%f- -*+,d3 !D)@$AAj()*?@$G
 ,,ABHHJ
Ut$;<=RSSPUD012GHM	 K DQ%DD()*?@ 	)) 		 !&
 	$$ 		 !!
 ;L:Q:QD	 !"67 	$$ 		 !!
 	** 		 !' >O=W=WD	 !"9:GOO$HLL 08D	 !),03GKK0@D	 !*- 	** 		 !" "$8 --9'8'M'M#$J t
 ( $$%:;tC#+!W__4#*??3D#E */*#*>>#6#6 <PD	 !"89 j55=T>48LD()&1 :+, (#8#I#I #8#I#I  ..:-;;AAC1Q D   7+ ? )+!	 yy{H55 //
*3!.?? 	6 	
	 KI  
s2   B V#V  :HV=KV VVVVc                     d }| 6| j                  d      }d| v r!| d   }d|v r|g }|j                  |d          |j                  j                  dd       "|g }|j                  |j                  d          |S )Nenforced_paramsservice_account_settings)rV   r   r*   )rl   rN   r   r   s       r    _get_enforced_paramsr   x  s     '+O#*../@A%)99'78R'S$ $<<"*&(O&&'?@Q'RS!!%%&7>J" O099:KLMr"   r   r   c                    t        ||      }|y|-|dur)t        d| dt        j                  j                         |D ]  }|j                  d      }t        |      dk(  r|d   | vs*t        d|d    d	      t        |      d
k(  sK|d   | vrt        d|d    d	      |d   | |d      vsrt        d|d    d|d    d       y)z]
    If enforced params are set, check if the request body contains the enforced params.
    )rl   rN   Tz;Enforced Params is an Enterprise feature. Enforced Params: z. .   r   zBadRequest please pass param=z* in request body. This is a required param   zBadRequest please pass param=[z][z+] in request body. This is a required param)r   
ValueErrorr   not_premium_userr   r   r   )r   rl   rN   r   r   enforced_param_enforced_paramss          r    r   r     sT    ';)=N'O "|4'?I/IZZ\]n]]  ^F  ^F  ]G  H
 	
 *)//4 A%",6 34DQ4G3HHrs  !"a'",6 34DQ4G3HHrs   ",7G7J*KK 45Ea5H4IL\]^L_K`  aL  M  *" r"   r   c                     |j                   rJd|j                   v r<ddlm} |durt        dt        j
                         |j                   d   | |   d<   yd| v r| d   | |   d<   | d= d| v r| d   | |   d<   | d= yy)z
    Heper to add guardrails from request to metadata

    - If guardrails set on API Key metadata then sets guardrails on request metadata
    - If guardrails not set on API key, then checks request metadata

    
guardrailsr   )r   TzUsing Guardrails on API Key Nguardrail_config)r*   r   r   r   r   r   )r/   r   rN   r   s       r    r   r     s     !!,555?4' 23D3U3U2VW  ;L:T:T;D(),7 t6:<6H$%l3T!<@AS<T$%&89#$ "r"   c                     ddg}| j                  di       xs i }d}|D ]!  }||v s||   }|j                  ||i       d}# |du r|| d<   y )Nzanthropic-versionzanthropic-betaextra_headersFT)rV   r   )r/   r]   ANTHROPIC_API_HEADERSr   added_headerrf   header_values          r    r   r     sz    
 	
 HH_b17RM L'W"6?L  &,!78L	 ( t -_
r"   c                     ddl m} | y |y t        j                  du rB|j                  r5d|j                  v r&d| vri | d<   | d   }d|vr|j                  d   |d<   y y y y y )Nr   )open_telemetry_loggerTtraceparentr   )r   r   rI   #forward_traceparent_to_llm_providerr]   )r/   r#   r   _exra_headerss       r    r   r     s    @|$ 	22d:??/ #$.,.D) $_ 5 53:??=3QM-0 6 0  ;r"   r   )NN)4r   r   r   typingr   r   r   r   r   fastapir   starlette.datastructuresr	   rI   litellm._loggingr
   r   litellm._service_loggerr   litellm.proxy._typesr   r   r   r   r   r   litellm.types.servicesr   litellm.types.utilsr   r   r   r   r   _ProxyConfigr!   r9   r.   r5   r;   rM   r\   re   rX   r   r   r   r   r   r   r   r   rT   r"   r    <module>r     s      < <  ,  A 2  0
 $%  FKK S &
 
 
$&
$&7?@T7U$&$&N&!%&!5@&!"#&!T @D/7}	"A
 A
R 26!|
|| &| 	|
 tCH~.| c]|~tn9Gd^&$$tn$ &$ 	$
 
$N %
 %  % & %F
2R Rw Rr"   