o
    ưiD                     @   s  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 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mZmZ d d	l m!Z! d d
l"m#Z# 	d*de$dee$ de%fddZ&dee$ dede#de$dee$ f
ddZ'	d*dedee( de#de$dede$dee$ deeee f fddZ)dd Z*dd Z+d d! Z,d"d# Z-d$e%ded%e$fd&d'Z.d(d) Z/dS )+    )datetimewraps)OptionalTuple)HTTPExceptionRequestN)verbose_logger)uuid)BudgetNewRequestDeleteCustomerRequestDeleteTeamRequestDeleteUserRequest
KeyRequestLiteLLM_BudgetTableLiteLLM_TeamMembershipLiteLLM_UserTable ManagementEndpointLoggingPayloadMemberSSOUserDefinedValuesUpdateCustomerRequestUpdateKeyRequestUpdateTeamRequestUpdateUserRequestUserAPIKeyAuthVirtualKeyEvent)_read_request_body)PrismaClientuser_id
user_emailreturnc                 C   sp   t jpi }|dpg |dt j|dt j|p|dd | dd}i }| D ]\}}|d ur5|||< q)|S )Nmodels
max_budgetbudget_durationr   Zinternal_user)r!   r"   r#   r   r   	user_role)litellmZdefault_internal_user_paramsgetZmax_internal_user_budgetZinternal_user_budget_durationitems)r   r   	user_infoZreturned_dictZnon_null_dictkv r+   ]/home/app/Keep/.python/lib/python3.10/site-packages/litellm/proxy/management_helpers/utils.pyget_new_internal_user_defaults#   s    
r-   existing_budget_iduser_api_key_dictprisma_clientlitellm_proxy_admin_namec                    s  ddl m} tj  t| dr| jddn| } fdd| D }t| dd	}|d	u rc|d	ur4|S |ratdi |}	|	|	jdd}
|j
jji |
|jpQ||jpU|d
dI d	H }|jS d	S |ru|tdd|i||dI d	H  |d	ur||kr|S |S )a?  
    Common helper to handle budget creation/updates for entities (organizations, tags, etc).
    
    This function:
    1. Creates a new budget if budget_id is None but budget fields are provided
    2. Updates an existing budget if budget fields are provided and budget_id exists
    3. Returns the budget_id to use (existing or newly created)
    
    Args:
        data: The request object (e.g., TagNewRequest, NewOrganizationRequest, etc.) containing budget fields
        existing_budget_id: The existing budget_id if updating an entity, None if creating new
        user_api_key_dict: User authentication info
        prisma_client: Database client
        litellm_proxy_admin_name: Admin name for audit trail
        
    Returns:
        Optional[str]: The budget_id to use, or None if no budget was created/updated
    r   )update_budget
model_dumpT)Zexclude_nonec                    s   i | ]\}}| v r||qS r+   r+   ).0r)   r*   Zbudget_paramsr+   r,   
<dictcomp>\   s    z,handle_budget_for_entity.<locals>.<dictcomp>	budget_idN)
created_by
updated_bydata)Z
budget_objr/   r+   )Z>litellm.proxy.management_endpoints.budget_management_endpointsr2   r   Zmodel_fieldskeyshasattrr3   r'   getattrZjsonify_objectdblitellm_budgettablecreater   r7   r   )r;   r.   r/   r0   r1   r2   Z
_json_dataZ_budget_dataZdata_budget_idZ
budget_rowZnew_budget_dataZ_budgetr+   r5   r,   handle_budget_for_entity:   sH   

rB   
new_membermax_budget_in_teamteam_iddefault_team_budget_idc                    s(  d}d}| j dur:t| j d}	|jjjd| j idd|giid|gi|	ddI dH }
|
dur9tdi |
 }n| jdurttt	
 | jd}	|jd	| jid
ddI dH }|du sgt|trt|dkr|g|	d< |j|	d
dI dH }
|
durtdi |
 }n:t|dkr|d }|jjjd|j idd|giidI dH }
|
durtdi |
 }nt|dkrtdddid|dur|jjj||j p||j p|ddI dH }|j}n|}|r|dur|j dur|jjj||j |dddidI dH }tdi | }|du rtd||fS )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   Zteamspush)updaterA   )wherer;   )r   r   r   userZfind_all)Zkey_val
table_nameZ
query_typer   )r;   rK      i  errorzIMultiple users with this email found in db. Please use 'user_id' instead.)status_codedetail)r"   r8   r9   r:   )rE   r   r7   Zlitellm_budget_tableT)r;   includez8Unable to update user table with membership information!r+   )r   r-   r?   Zlitellm_usertableZupsertr   r3   r   strr
   uuid4get_data
isinstancelistlenZinsert_datarH   r   r@   rA   r7   Zlitellm_teammembershipr   	Exception)rC   rD   r0   rE   r/   r1   rF   Zreturned_userZreturned_team_membershipZnew_user_defaultsZ_returned_userZexisting_user_rowr(   responseZ
_budget_idZ_returned_team_membershipr+   r+   r,   add_new_member   s   


	

rY   c                 C   b   ddl m} | dd ur/| d}t|tr|j|jd t|tr/|jD ]}|j|d q&d S Nr   )user_api_key_cacher;   )key)	litellm.proxy.proxy_serverr\   r&   rT   r   delete_cacher   r   user_ids)kwargsr\   Zupdate_user_requestr   r+   r+   r,   _delete_user_id_from_cache      



rb   c                 C   sh   ddl m} | dd ur2| d}t|tr|j|jd t|tr2|jr2|jD ]}|j|d q)d S r[   )	r^   r\   r&   rT   r   r_   r]   r   r<   )ra   r\   update_requestr]   r+   r+   r,   _delete_api_key_from_cache  s   


re   c                 C   rZ   r[   )	r^   r\   r&   rT   r   r_   rE   r   Zteam_ids)ra   r\   rd   rE   r+   r+   r,   _delete_team_id_from_cache  rc   rf   c                 C   rZ   r[   )	r^   r\   r&   rT   r   r_   r   r   r`   )ra   r\   rd   r   r+   r+   r,   _delete_customer_id_from_cache"  rc   rg   request_kwargsfunction_namec           	   
      s   ddl m} ddlm} |j|j|j|j|j|j	|j
|j|jd	}|durX|jdurZ||v r\|| }t|jp8d|jp<d|j| d}|dd	 }|jj|||d
I dH  dS dS dS dS )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   )proxy_logging_obj)	AlertType)	Zgenerate_key_fnZupdate_key_fnZdelete_key_fnZnew_teamZupdate_teamZdelete_teamZnew_userZuser_updateZdelete_userNUnknown)Zcreated_by_user_idZcreated_by_user_roleZcreated_by_key_aliasrh   _ )	key_event
event_nameZ
alert_type)r^   rj   Z)litellm.types.integrations.slack_alertingrk   Znew_virtual_key_createdZvirtual_key_updatedZvirtual_key_deletedZnew_team_createdZteam_updatedZteam_deletedZnew_internal_user_createdZinternal_user_updatedZinternal_user_deletedZslack_alerting_instancer   r   r$   Z	key_aliasreplacetitleZsend_virtual_key_event_slack)	rh   r/   ri   rj   rk   Z!management_function_to_event_nameZ_event_namero   rp   r+   r+   r,   send_management_endpoint_alert1  s@   
rs   c                    s   t   fdd}|S )z{
    This wrapper does the following:

    1. Log I/O, Exceptions to OTEL
    2. Create an Audit log for success calls
    c                     s
  t  }d }z | i |I d H }t  }zv|d u ri }|dp$t }t|| jdI d H  |dd }t|dd }|d uruddlm} |d uru|ru|j	j
}	t|dI d H }
|d ur`t|nd }t|	|
|||d}|j||d	I d H  t|d
 t|d
 t|d
 t|d
 W |W S  ty } ztdt| W Y d }~|W S d }~ww  ty } zOt  }|d u ri }|dpt }t|dd }|d urddlm} |d ur|d}|r|j	j
}	t|dI d H }
t|	|
d |||d}|j||d	I d H  |d }~ww )Nr/   )rh   r/   ri   http_requestparent_otel_spanr   )open_telemetry_logger)request)routerequest_datarX   
start_timeend_time)logging_payloadru   )ra   z(Error in management endpoint wrapper: %s)rx   ry   rX   rz   r{   	exception)r   nowr&   r   rs   __name__r>   r^   rv   urlpathr   dictr   Z&async_management_endpoint_success_hookre   rb   rf   rg   rW   r	   debugrQ   Z&async_management_endpoint_failure_hook)argsra   rz   Z_http_requestresultr{   r/   ru   rv   Z_routeZ_request_body	_responser|   efuncr+   r,   wrappern  s   




	z,management_endpoint_wrapper.<locals>.wrapperr   )r   r   r+   r   r,   management_endpoint_wrapperf  s   Zr   )N)0r   	functoolsr   typingr   r   Zfastapir   r   r%   Zlitellm._loggingr	   Zlitellm._uuidr
   Zlitellm.proxy._typesr   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   Z-litellm.proxy.common_utils.http_parsing_utilsr   Zlitellm.proxy.utilsr   rQ   r   r-   rB   floatrY   rb   re   rf   rg   rs   r   r+   r+   r+   r,   <module>   sv   L

Z
h
5