
    g7                     >   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	 d dl
Z
d dlmZ d dlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ d dlmZ d d	lm Z  	 dd
e!dee!   de"fdZ#dedee$   de de!dede!deeee   f   fdZ%d Z&d Z'd Z(d Z)de"dede!fdZ*d Z+y)    N)datetimewraps)OptionalTuple)HTTPExceptionRequest)verbose_logger)DeleteCustomerRequestDeleteTeamRequestDeleteUserRequest
KeyRequestLiteLLM_TeamMembershipLiteLLM_UserTable ManagementEndpointLoggingPayloadMemberSSOUserDefinedValuesUpdateCustomerRequestUpdateKeyRequestUpdateTeamRequestUpdateUserRequestUserAPIKeyAuthVirtualKeyEvent)_read_request_body)PrismaClientuser_id
user_emailreturnc                 D   t         j                  xs i }|j                  dd       |j                  dt         j                        |j                  dt         j                        |xs |j                  dd       | dd}i }|j                         D ]  \  }}|	|||<    |S )Nmodels
max_budgetbudget_durationr   internal_user)r    r!   r"   r   r   	user_role)litellmdefault_internal_user_paramsgetmax_internal_user_budgetinternal_user_budget_durationitems)r   r   	user_inforeturned_dictnon_null_dictkvs          [/var/www/openai/venv/lib/python3.12/site-packages/litellm/proxy/management_helpers/utils.pyget_new_internal_user_defaultsr1   !   s     44:I --$/mmL'2R2RS$==wDD
 !EIMM,$E$	+M M##%1= M! &     
new_membermax_budget_in_teamprisma_clientteam_iduser_api_key_dictlitellm_proxy_admin_namec                   K   d}d}| j                   |t        | j                         }|j                  j                  j	                  d| j                   idd|giid|gi|d       d{   }	|	kt        di |	j                         }nP| j                  Ct        t        t        j                               | j                        }|j                  d	| j                  id
d       d{   }
|
t        |
t              rKt        |
      dk(  r=|g|d<   |j                  |d
       d{   }	|	t        di |	j                         }nt        |
      dk(  ra|
d   }|j                  j                  j!                  d|j                   idd|gii       d{   }	|	7t        di |	j                         }nt        |
      dkD  rt#        dddi      |||j                   |j                  j$                  j'                  ||j                   xs ||j                   xs |d       d{   }|j(                  }|j                  j*                  j'                  ||j                   |dddi       d{   }t-        di |j                         }|t/        d      ||fS 7 F7 7 7 7 7 <w)z
    Add a new member to a team

    - add team id to user table
    - add team member w/ budget to team member table

    Returns created/existing user + team membership w/ budget id
    N)r   r   teamspush)updatecreate)wheredata)r   r   r   userfind_all)key_val
table_name
query_typer   )r?   rC      i  errorzIMultiple users with this email found in db. Please use 'user_id' instead.)status_codedetail)r!   
created_by
updated_by)r?   )r6   r   	budget_idlitellm_budget_tableT)r?   includez8Unable to update user table with membership information! )r   r1   dblitellm_usertableupsertr   
model_dumpr   struuiduuid4get_data
isinstancelistleninsert_datar<   r   litellm_budgettabler=   rK   litellm_teammembershipr   	Exception)r3   r4   r5   r6   r7   r8   returned_userreturned_team_membershipnew_user_defaults_returned_userexisting_user_rowr+   response
_budget_id_returned_team_memberships                  r0   add_new_memberrf   8   s.      26MAE%::CUCUV,//AAHHj001"VgY$78"WIC1BC  I  
 
 %-L0I0I0KLM				*:

%*2G2G

 3@2H2H!:#8#89! 3I 3
 -

 $($/C8I4Ja4O*1g&#0#<#<BS`f#<#ggN) 1 PN4M4M4O P"#q()!,I#0#3#3#E#E#L#L )"3"34	23 $M $ N ) 1 PN4M4M4O P"#a'h  	&%!!- '))==DD0/77S;S/77S;S E 
 
 ''
""99@@&,44!+
 06 A   	" $: $
'224$
  RSS222]
-
 h*
sq   A*K,J2-BK1J52A K2J83A.K!J;"BK8J>9A
KK /K5K8K;K>K Kc                    ddl m} | j                  d      p| j                  d      }t        |t              r|j                  |j                         t        |t              r#|j                  D ]  }|j                  |        y Nr   )user_api_key_cacher?   )key)	litellm.proxy.proxy_serverri   r'   rW   r   delete_cacher   r   user_ids)kwargsri   update_user_requestr   s       r0   _delete_user_id_from_cacherp      sy    =zz&%$jj0)+<=++0C0K0K+L )+<=.77"//G/< 8r2   c                    ddl m} | j                  d      p| j                  d      }t        |t              r|j                  |j                         t        |t              r#|j                  D ]  }|j                  |        y rh   )	rk   ri   r'   rW   r   rl   rj   r   keys)rn   ri   update_requestrj   s       r0   _delete_api_key_from_cachert      st    =zz&%F+n&67++0B0B+C nj1%**"//C/8 +r2   c                    ddl m} | j                  d      p| j                  d      }t        |t              r|j                  |j                         t        |t              r#|j                  D ]  }|j                  |        y rh   )	rk   ri   r'   rW   r   rl   r6   r   team_ids)rn   ri   rs   r6   s       r0   _delete_team_id_from_cacherw      su    =zz&%F+n&78++0F0F+G n&78)22"//G/< 3r2   c                    ddl m} | j                  d      p| j                  d      }t        |t              r|j                  |j                         t        |t              r#|j                  D ]  }|j                  |        y rh   )	rk   ri   r'   rW   r   rl   r   r   rm   )rn   ri   rs   r   s       r0   _delete_customer_id_from_cachery      su    =zz&%F+n&;<++0F0F+G n&;<)22"//G/< 3r2   request_kwargsfunction_namec           
      ,  K   ddl m}m} ddlm} |dury|j
                  |j                  |j                  |j                  |j                  |j                  |j                  |j                  |j                  d	}||j                  ||v r||   }t        |j                   xs d|j"                  xs d|j$                  |       }|j'                  d	d
      j)                         }	|j                  j+                  ||	|       d{    yyyy7 w)z
    Sends a slack alert when:
    - A virtual key is created, updated, or deleted
    - An internal user is created, updated, or deleted
    - A team is created, updated, or deleted
    r   )premium_userproxy_logging_obj)	AlertTypeTN)	generate_key_fnupdate_key_fndelete_key_fnnew_teamupdate_teamdelete_teamnew_useruser_updatedelete_userUnknown)created_by_user_idcreated_by_user_rolecreated_by_key_aliasrz   _ )	key_event
event_name
alert_type)rk   r}   r~   )litellm.types.integrations.slack_alertingr   new_virtual_key_createdvirtual_key_updatedvirtual_key_deletednew_team_createdteam_updatedteam_deletednew_internal_user_createdinternal_user_updatedinternal_user_deletedslack_alerting_instancer   r   r$   	key_aliasreplacetitlesend_virtual_key_event_slack)
rz   r7   r{   r}   r~   r   !management_function_to_event_name_event_namer   r   s
             r0   send_management_endpoint_alertr      s/     KC4 %<<"66"66.. -- --77 66 66)%  	%55A ==%F}%UK'#4#<#<#I	%6%@%@%MI%6%@%@-	I %,,S#6<<>J#;;XX#%& Y    >	 B 	&"s   DD	D
	Dc                 .     t                fd       }|S )z{
    This wrapper does the following:

    1. Log I/O, Exceptions to OTEL
    2. Create an Audit log for success calls
    c            	        K   t        j                         }d }	  | i | d {   }t        j                         }	 |i }|j                  d      xs
 t               }t	        ||j
                         d {    |j                  dd       }t        |dd       }|nddlm} |f|rd|j                  j                  }	t        |       d {   }
|t        |      nd }t        |	|
|||      }|j                  ||	       d {    t        |
       t!        |
       t#        |
       t%        |
       |S 7 7 7 u7 =# t&        $ r*}t)        j*                  dt-        |             Y d }~|S d }~ww xY w# t&        $ r}t        j                         }|i }|j                  d      xs
 t               }t        |dd       }|sddlm} |k|j                  d      }|rX|j                  j                  }	t        |       d {  7  }
t        |	|
d |||      }|j/                  ||	       d {  7   |d }~ww xY ww)Nr7   )rz   r7   r{   http_requestparent_otel_spanr   )open_telemetry_logger)request)routerequest_datarc   
start_timeend_time)logging_payloadr   )rn   z(Error in management endpoint wrapper: %s)r   r   rc   r   r   	exception)r   nowr'   r   r   __name__getattrrk   r   urlpathr   dictr   &async_management_endpoint_success_hookrt   rp   rw   ry   r]   r
   debugrS   &async_management_endpoint_failure_hook)argsrn   r   _http_requestresultr   r7   r   r   _route_request_body	_responser   efuncs                 r0   wrapperz,management_endpoint_wrapper.<locals>.wrapper  s    \\^
+/U	000F||~H.>FJJ23G~7G " 5#)&7"&--  
 !'

>4 @#*+<>PRV#W #/P,8(%2%6%6%;%;F8J(59 3M 9?8JVPTI.N&,-:)2+5)1/O #8"^"^0?1A #_ #   +&9*&9*&9.f= Me 13  $$%OQTUVQWXM  !	||~H~

./C>3C   ''8:LdS+L(4$*JJ~$>M$!.!2!2!7!74F$15 / / +K"()6%)'1%-&'+ 4ZZ,;-= [   
 GC!	s   IF EF  <E <E=AE E9E E	4E  F IF E E 	E 	E>E93F 8I9E>>F 	I
BIH,I;H><IIIr   )r   r   s   ` r0   management_endpoint_wrapperr     s%     4[X Xt Nr2   )N),rT   r   	functoolsr   typingr   r   fastapir   r	   r%   litellm._loggingr
   litellm.proxy._typesr   r   r   r   r   r   r   r   r   r   r   r   r   r   r   -litellm.proxy.common_utils.http_parsing_utilsr   litellm.proxy.utilsr   rS   r   r1   floatrf   rp   rt   rw   ry   r   r   rN   r2   r0   <module>r      s      " *  +    " M , /3&sm	.c3c3 c3  c3 	c3
 &c3 "c3 h'=>>?c3L				66%6 6rcr2   