
    ^hPl                     .   S SK r S SKrS SKJrJrJrJrJr  S SKJ	r	  S SK
Jr  S SKrS SKJrJr  S SKJr  S SKJrJrJrJrJrJr  S SKJr  S S	KJrJr  \" 5       r\(       a	  S S
KJ r!  \!r O\r S r"S\	S\#4S jr$S\%S\	4S jr&S\S\\   S\4S jr'S\S\\   4S jr( S&S\S\\#   S\%4S jjr) " S S5      r*  S'S\%S\	S\S\ S\\\#\4      S\\#   4S jjr+S\\%   S\S\\,   4S jr-S\%S\\%   S\S \.S\.4
S! jr/S\%S"\#S\4S# jr0S\%S\%4S$ jr1S\%S\	4S% jr2g)(    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                     0 nU R                  S5      nU H&  nSU;   a  UR                  S5      u  pEXQU'   M"  SX'   M(     U$ )Nz, =T)split)cache_control
cache_dict
directives	directivekeyvalues         ^/home/james-whalen/.local/lib/python3.13/site-packages/litellm/proxy/litellm_pre_call_utils.pyparse_cache_controlr!   $   sP    J$$T*J	)"-JC#sO$(J!       requestreturnc                     SU R                   R                  ;   d  SU R                   R                  ;   a  gSU R                   R                  ;   a  gSU R                   R                  ;   a  gg)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.   2   sW     7;;###{gkk6F6F'F!GKK$$$!)))!r"   datac                      [        US5      (       a%  [        UR                  5      nSU;   a	  US   U S'   g g g ! [         a     g [         a*  n[
        R                  " S[        U5      5         S nAg S nAff = f)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;   E   s~    

7N++ 4 45L,&2=&A]# - ,   
  <c!f	
 	

s   49 
A8	A8 A33A8team_callback_settings_objc                    Uc
  [        5       nU R                  S:X  aU  UR                  c  / Ul        U R                  UR                  ;  a%  UR                  R	                  U R                  5        GOU R                  S:X  aT  UR
                  c  / Ul        U R                  UR
                  ;  a%  UR
                  R	                  U R                  5        OU R                  S:X  a  UR                  c  / Ul        UR
                  c  / Ul        U R                  UR                  ;  a%  UR                  R	                  U R                  5        U R                  UR
                  ;  a%  UR
                  R	                  U R                  5        U R                  R                  5        HU  u  p#UR                  c  0 Ul        [        [        R                  R                  X3S9=(       d    U5      UR                  U'   MW     U$ )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   S   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
%33;79&48;MM$$U$@IE9
"005 1 &%r"   user_api_key_dictc                 T   S nU R                   b;  SU R                   ;   a+  U R                   S    H  n[        [        S0 UD6US9nM     U$ U R                  bP  U R                  nSU;   a>  UR	                  SS 5      =(       d    0 n[        S0 UD6n[        R                  " SU5         U$ )Nlogging)r/   r<   callback_settingsz$Team callback settings activated: %s )r*   rM   r   team_metadatagetr   r   debug)rN   callback_settings_objitemrS   rQ   s        r    _get_dynamic_logging_metadatarX   z   s     =A"".*333%..y9D$L$,t,+@%! :. ! % 
	(	(	4)77-/ - 1 12Et L RPR$8$M;L$M! &&68M ! r"   headerslitellm_key_header_namec                 L   [         R                  R                  5        Vs/ s H  o"R                  R	                  5       PM     nnUnUb  UR                  UR	                  5       5        0 nU R                  5        H  u  pVUR	                  5       U;  d  M  XdU'   M!     U$ s  snf )z&
Removes litellm api key from headers
)r   _member_map_valuesr   lowerrE   rH   )rY   rZ   vspecial_headersclean_headersheaderr   s          r    ra   ra      s     1?0K0K0R0R0TU0T1ww}}0TOU%O*6<<>?M <<>0$)&! )  Vs   #B!c                   ,   \ rS rSr\S\\\4   4S j5       r\ SS\S\	\
   S\	\   4S jj5       r\S\S\S\4S	 j5       r\SS
.S\S\S\	\
\\4      S\4S jj5       r\S\S\4S j5       r\S\S\S\4S j5       r\S\	\   S\	\   S\4S j5       rSrg)LiteLLMProxyRequestSetup   rY   c                     0 nU R                  5        HU  u  p#UR                  5       R                  S5      (       d  M+  UR                  5       R                  S5      (       a  MQ  X1U'   MW     U$ )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   r^   
startswith)rY   forwarded_headersrb   r   s       r    _get_forwardable_headers1LiteLLMProxyRequestSetup._get_forwardable_headers   s`     $]]_MF||~((..v||~7P7P8 8 -2&)	 - ! r"   Ngeneral_settingsr$   c                     Ub  UR                  S5      SLa  gU R                  5        H  u  p#UR                  5       S:X  d  M  Us  $    g)z)
Get the OpenAI Org ID from the headers.
Nforward_openai_org_idTzopenai-organization)rT   rH   r^   )rY   rk   rb   r   s       r    get_openai_org_id_from_headers7LiteLLMProxyRequestSetup.get_openai_org_id_from_headers   sL     ( $$%<=TI$]]_MF||~!66 - r"   rN   c                     [         R                  U 5      n[        R                  SL aD  [         R	                  US9nUR                  5        H  u  pEUc  M
  XRSR                  U5      '   M     U$ )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-{})rd   ri   rI   #add_user_information_to_llm_headers'get_sanitized_user_information_from_keyrH   format)rY   rN   returned_headers litellm_logging_metadata_headerskr_   s         r    add_headers_to_llm_call0LiteLLMProxyRequestSetup.add_headers_to_llm_call   sw     4LLWU66$>(PP&7 Q  -
 9>>@=AB^%:%:1%=> A  r"   )rk   c                     [        5       nU(       a3  UR                  S5      SL a  [        R                  X5      nU0 :w  a  XCS'   [        R	                  X5      nUb  XSS'   U$ )z*
- Adds forwardable headers
- Adds org id
!forward_client_headers_to_llm_apiTrY   organization)r   rT   rd   rx   rn   )rY   rN   rk   r/   _headers_organizations         r    %add_litellm_data_for_backend_llm_call>LiteLLMProxyRequestSetup.add_litellm_data_for_backend_llm_call   sn     ,- $$%HITQ/GGH 2~"*Y0OO
 $#0 r"   c           
          [        U R                  U R                  U R                  U R                  U R
                  U R                  U R                  S9nU$ )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_aliasteam_iduser_idorg_id
team_aliasend_user_id)rN   user_api_key_logged_metadatas     r    rs   @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                    UR                  5       nSU ;   aL  0 US'   [        U S   [        5      (       a/  U S   R                  5        H  u  p4U[        ;   d  M  XAS   U'   M     SU ;   a3  U S   b-  [
        R                  X   R                  S5      U S   S9X   S'   SU ;   ax  [        U S   [        5      (       a`  SX   ;   aN  [        X   S   [        5      (       a4  U S   R                  5        H  u  pVXQU   S   ;  d  M  UX   S   U'   M     O
U S   X   S'   SU ;   a   [        U S   [        5      (       a  U S   US'   U$ )Ncachetagsrequest_tagstags_to_addspend_logs_metadatadisable_fallbacks)	copy
isinstancer5   rH   r   rd   _merge_tagsrT   bool)r   r/   r   rw   r_   r   r   s          r    add_key_level_controls/LiteLLMProxyRequestSetup.add_key_level_controls  s    yy{l"DM,w/66(1779DA22+,Wa( :
 \!l6&:&F(44!%!>!B!B6!J ,V 4 5  )&1 !L0Z./6
 6
 %(EE*-.CDdK K #//D"E"K"K"MJC(?#@AV#WW " 56KL	 #N HT)H-.CD
 ,.:,-t4
 4
 )55H(ID$%r"   r   r   c                     / nU (       a&  [        U [        5      (       a  UR                  U 5        U(       a6  [        U[        5      (       a!  U H  nX2;  d  M
  UR                  U5        M     U$ )z
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   $LiteLLMProxyRequestSetup._merge_tagsB  s[     
J|T::l+:k488"(%%c* # r"   rR   N)__name__
__module____qualname____firstlineno__staticmethodr   r	   r5   ri   r   r   r9   rn   r   rx   r   r   r   r   rs   r   r   r   __static_attributes__rR   r"   r    rd   rd      sW   !w}%! !" :>)1$	#     *8 	   0 
 6:	 * #4S>2	
 
& 6 ,),	*, , **"&*AD* *X (4. x~ RV  r"   rd   proxy_configrk   versionc           	        #    SSK JnJn  [        X5        [	        UR
                  Ub  UR                  S5      OSS9nU R                  [        R                  UUUS95        [        UR                  5      UR                  U[        R                  " U 5      S.U S'    UR                  n	[        U	5      n
U
R                  S	5      nUb  XS
'   [#        XS9  UR
                  n[$        R&                  " SU5        UR                  SS5      nU(       a  [)        U5      nUR                  S5      U S'   [$        R&                  " SU 5        [+        U5      nX;  a  0 X'   SU ;   a$  U S   b  [        R,                  " U S   5      X   S'   [        R/                  US9nX   R                  U5        UR0                  X   S'   [3        USS5      X   S'   XPU   S'   Ub  UR                  SS5      X   S'   UR4                  n[        R7                  UU US9n UR8                  =(       d    0 nSU;   a3  US   b-  [        R;                  X   R                  S5      US   S9X   S'   SU;   ay  [=        US   [        5      (       aa  SX   ;   aO  [=        X   S   [        5      (       a5  US   R?                  5        H  u  nnUX   S   ;  d  M  UX   S   U'   M     O
US   X   S'   UR@                  X   S'   URB                  X   S'   URD                  X   S'   URF                  X   S '   URH                  X   S!'   UR4                  X   S"'   [        UR
                  5      nURK                  S#S5        XU   S$'   [        UR                  5      X   S%'   URL                  X   S&'   [O        XS'9  URP                  b  URP                  U S('   [R        RR                  " 5       nS)nUS*L a  UbH  UR                  S+5      S*L a4  Ub1  [U        US$5      (       a   S,UR
                  ;   a  UR
                  S,   nORUbO  [U        US-5      (       a>  [U        URV                  S.5      (       a#  URV                  b  URV                  RX                  nUX   S/'   U(       a  URZ                  S*L a  SU ;   a
  U S   X   S'   UR\                  bP  UR_                  UR\                  S09I Sh  vN n[a        U5      S:X  a  OURK                  S1S5      nUX   S1'   0 UEU En [c        US9nUbT  URd                  U S2'   URf                  U S3'   URh                  b)  URh                  R?                  5        H  u  nnUU U'   M     [k        U UUS49  [$        R&                  " S5U  35        [m        U UUUS69  [R        RR                  " 5       n[n        Rq                  [r        Rt                  UU-
  S7UUURL                  S89I Sh  vN   U $ ! [          a    0 n
 GNAf = f GN) N7f)9a  
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_userNrZ   )rZ   )rY   rN   rk   )r+   methodrY   bodyproxy_server_requestr2   r3   )r/   rY   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authorizationrY   endpointlitellm_parent_otel_spanr-   allowed_model_region Tuse_x_forwarded_forzx-forwarded-forclienthostrequester_ip_address)r   r   rC   rF   )r/   r   rN   z2[PROXY]returned data from litellm_pre_call_utils: )request_bodyrk   rN   r   add_litellm_data_to_request)serviceduration	call_type
start_timeend_timeparent_otel_span);litellm.proxy.proxy_serverr   r   r;   ra   rY   rT   updaterd   r   r9   r+   r   r   r1   r5   r6   (add_provider_specific_headers_to_requestr   rU   r!   r.   deepcopyrs   r   getattrr*   r   rS   r   r   rH   team_max_budget
team_spendspend
max_budgetmodel_max_budgetpopr   _add_otel_traceparent_to_datar   timer4   r   r   enable_tag_filteringr   load_team_configlenrX   rC   rF   rG   move_guardrails_to_metadata_enforced_params_checkservice_logger_objasync_service_success_hookr   PROXY_PRE_CALL)r/   r#   rN   r   rk   r   r   r   r}   r1   
query_dictdynamic_api_versionrY   cache_control_headerr   r   r   r   rS   r   r   r   r   team_configr   rV   rw   r_   r   s                                r    r   r   [  s    , D*49  +   !:;H 	KK FF/- 	G 	
 7;;..		$	$D	 ++,'

 *4)F&1] -$I ooG4g>";;=()=>
 nnZ0U3T:9'B*(*% Td:.:>Bmm?
%&:;
 	!HH/ 	I 	
 !
 	!(()EF 	!! 	! EL0$ED!"@A <C	 !"78#  !?F 	%&DE
 %--L#::! 7 ; D &339rM=#8#D0H0T0T6::6B%f- 1U 1
%f- -*+,d3 3 !D$AAj)*?@$G
 G
 ,,ABHHJ
Ut<=RSSPUD12GHM	 K DQ%DD)*?@ 	)) 	!&
 	$$ 	!!
 ;L:Q:QD!"67 	$$ 	!!
 	** 	!' >O=W=WD!"9:GOO$HLL 08	 !),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   ,(99%-- : 
 
 {q !ooi6G7>D))4D :+ (#8#I#I #8#I#I  ..:-;;AAC1Q D   7+ 
<TFC )+!	 yy{H

7
7++J&/*;; 8    Kc  
r
`sQ   BW?W' 5HW?HW?W:DW? W=!W?'W73W?6W77W?=W?c                    S nU b;  U R                  S5      nSU ;   a$  U S   nSU;   a  Uc  / nUR                  US   5        UR                  R                  SS 5      b#  Uc  / nUR                  UR                  S   5        U$ )Nenforced_paramsservice_account_settings)rT   r   r*   )rk   rN   r   r   s       r    _get_enforced_paramsr   g  s     '+O#*../@A%)99'78R'S$ $<<"*&(O&&'?@Q'RS!!%%&7>J" O099:KLMr"   r   r   c                    [        XS9nUc  gUb.  USLa)  [        SU S[        R                  R                   35      eU H  nUR                  S5      n[        U5      S:X  a  US   U ;  a  [        SUS    S	35      eM@  [        U5      S
:X  d  MQ  US   U ;  a  [        SUS    S	35      eUS   XS      ;  d  M|  [        SUS    SUS    S35      e   g)zU
If enforced params are set, check if the request body contains the enforced params.
)rk   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   rk   rN   r   r   enforced_param_enforced_paramss          r    r   r   z  sS    ';)'O "|4'?I/IZZ\]n]]  ^F  ^F  ]G  H
 	
 *)//4 A%",6 34DQ4G3HHrs  7 !"a'",6 34DQ4G3HHrs   ",7J*KK 45Ea5H4IL\]^L_K`  aL  M  *" r"   r   c                    UR                   (       aL  SUR                   ;   a<  SSKJn  USLa  [        S[        R
                   35      eUR                   S   X   S'   gSU ;   a  U S   X   S'   U S	 SU ;   a  U S   X   S'   U S	 gg)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                     SS/nU R                  S0 5      =(       d    0 nSnU H"  nXQ;   d  M
  X   nUR                  XV05        SnM$     USL a  X0S'   g )Nzanthropic-versionzanthropic-betaextra_headersFT)rT   r   )r/   rY   ANTHROPIC_API_HEADERSr   added_headerrb   header_values          r    r   r     sr    
 	
 HH_b17RM L'"?L  &!78L	 ( t -_
r"   c                     SSK Jn  U c  g Uc  g [        R                  SL aM  UR                  (       a;  SUR                  ;   a*  SU ;  a  0 U S'   U S   nSU;  a  UR                  S   US'   g g g g g )Nr   )open_telemetry_loggerTtraceparentr   )r   r  rI   #forward_traceparent_to_llm_providerrY   )r/   r#   r  _exra_headerss       r    r   r     s    @|$ 	22d:??/ #$.,.D) $_ 5 53:??=3QM-0 6 0  ;r"   r   )NN)3r   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   rX   ra   rd   r   r   r   r   r   r   r   r   rR   r"   r    <module>r     s     < <  ,  A 2  0
 $%  FKK S &
 
 
$&
$&7?@T7U$&$&N!%!"#!F @D/7}	"k kf 26!I
II &I 	I
 tCH~.I c]IXtn9Gd^&$$tn$ &$ 	$
 
$N %
 %  % & %F
2R Rw Rr"   