
    h<\              	          d Z ddlZddlmZmZ ddlZddlmZmZmZm	Z	m
Z
 ddlZddlmZ ddl ddlmZ  e       Zej%                  dd	g ee      gd
      ej%                  dd	g ee      g      defd              Zej%                  dd	g ee      gd
      ej%                  dd	g ee      g      defd              Zdedee   fdZej%                  dd	gd
 ee      g      ej%                  dd	g ee      g       ee      fdedefd              Zej7                  dd	g ee      ge      ej7                  dd	gd
 ee      g       ej:                  d      fdefd               Zej%                  d!d	g ee      g      ej%                  d"d	gd
 ee      g       ee      fde defd#              Z!ej%                  d$d	g ee      g      ej%                  d%d	gd
 ee      g       ee      fde"defd&              Z#ej7                  d'd	g ee      gee         ej7                  d(d	gd
 ee      g       ee      fd)e	defd*              Z$y)+z}
CUSTOMER MANAGEMENT

All /customer management endpoints 

/customer/new   
/customer/info
/customer/update
/customer/delete
    N)ListOptional)	APIRouterDependsHTTPExceptionRequeststatus)verbose_proxy_logger)*)user_api_key_authz/end_user/blockzCustomer ManagementF)tagsdependenciesinclude_in_schemaz/customer/block)r   r   datac                   K   ddl m} 	 g }|\| j                  D ]L  }|j                  j                  j                  d|i|ddddid	       d{   }|j                  |       N nt        d
ddi      d|iS 7 +# t        $ r>}t        j                  dt        |              t        d
dt        |      i      d}~ww xY ww)a  
    [BETA] Reject calls with this end-user id

    Parameters:
    - user_ids (List[str], required): The unique `user_id`s for the users to block

        (any /chat/completion call with this user={end-user-id} param, will be rejected.)

        ```
        curl -X POST "http://0.0.0.0:8000/user/block"
        -H "Authorization: Bearer sk-1234"
        -d '{
        "user_ids": [<user_id>, ...]
        }'
        ```
    r   prisma_clientNuser_idT)r   blockedr   )createupdatewherer     errorzPostgres DB Not connectedstatus_codedetailblocked_userszAn error occurred - )litellm.proxy.proxy_serverr   user_idsdblitellm_endusertableupsertappendr   	Exceptionr
   r   str)r   r   recordsidrecordes         q/var/www/Befach/backend/env/lib/python3.12/site-packages/litellm/proxy/management_endpoints/customer_endpoints.py
block_userr-      s     8 9G$mm,//DDKK$b/.0T"B#,d"3  L    v& $  !<= 
  ))  G""%9#a&#BCWc!f4EFFGs;   C	AA? A=*A? <C	=A? ?	C9CCC	z/end_user/unblockz/customer/unblockc                   K   	 ddl m t        fdt        j                  D              rt        j                  t        dddi      t        t        j                  t              r1| j                  D ]!  }t        j                  j                  |       # nt        ddd	i      d
t        j                  iS # t        $ r+ t        dddt        j
                  j                  z   i      w xY ww)z
    [BETA] Unblock calls with this user id

    Example
    ```
    curl -X POST "http://0.0.0.0:8000/user/unblock"
    -H "Authorization: Bearer sk-1234"
    -d '{
    "user_ids": [<user_id>, ...]
    }'
    ```
    r   )_ENTERPRISE_BlockedUserList  r   z:Blocked user check was never set. This call has no effect.r   c              3   6   K   | ]  }t        |        y w)N)
isinstance).0xr/   s     r,   	<genexpr>zunblock_user.<locals>.<genexpr>w   s     Vq
19:Vs   r   zF`blocked_user_list` must be set as a list. Filepaths can't be updated.r   )-enterprise.enterprise_hooks.blocked_user_listr/   ImportErrorr   CommonProxyErrors!missing_enterprise_package_dockervalueanylitellm	callbacksblocked_user_listr2   listr!   remove)r   r)   r/   s     @r,   unblock_userrA   Q   s     0
	
 VGDUDUVV$$,U
 	
 '++T2--B%%,,R0   a
 	
 W6677?  
U#EEKKL
 	

s   C3B< B1C3<4C00C3returnc                     t         j                  j                         }i }|D ]  }|dk(  r	t        | |d      }||||<    |rt        di |S y)zE
    Return a new budget object if new budget params are passed.
    	budget_idN )BudgetNewRequestmodel_fieldskeysgetattr)r   budget_paramsbudget_kv_pairs
field_namer:   s        r,   new_budget_requestrM      sh     %11668MO $
$j$/*/OJ' $ 2/22    z/end_user/new)r   r   r   z/customer/newuser_api_key_dictc                 @  K   	 ddl m}m}m} |'t	        ddt
        j                  j                  i      	 | j                  |'t	        ddt
        j                  j                  i      | j                  |j                         vr@t	        dddj                  | j                  t        |j                                     i      i }t        |       }|r	 |j                  j                  j!                  i |j#                  d	
      |j$                  xs ||j$                  xs |d       d{   }|j*                  |d<   n| j*                  | j*                  |d<   | j-                  d	      }	|	j/                         D ]+  \  }
}|
t0        j2                  j5                         vs'|||
<   - |j                  j6                  j!                  |dd	i       d{   }|S 7 # t&        $ r}t	        ddt)        |      i      d}~ww xY w7 1# t&        $ r}t9        j:                  dj                  t)        |                   dt)        |      v rt=        d| j$                   dddd      t?        |t              rKt=        tA        |ddt)        |       d      dtA        |dd      tA        |dtB        jD                               t?        |t<              r|t=        d!t)        |      z   dtA        |dd      tB        jD                         d}~ww xY ww)"a
  
    Allow creating a new Customer 


    Parameters:
    - user_id: str - The unique identifier for the user.
    - alias: Optional[str] - A human-friendly alias for the user.
    - blocked: bool - Flag to allow or disallow requests for this end-user. Default is False.
    - max_budget: Optional[float] - The maximum budget allocated to the user. Either 'max_budget' or 'budget_id' should be provided, not both.
    - budget_id: Optional[str] - The identifier for an existing budget allocated to the user. Either 'max_budget' or 'budget_id' should be provided, not both.
    - allowed_model_region: Optional[Union[Literal["eu"], Literal["us"]]] - Require all user requests to use models in this specific region.
    - default_model: Optional[str] - If no equivalent model in the allowed region, default all requests to this model.
    - metadata: Optional[dict] = Metadata for customer, store information for customer. Example metadata = {"data_training_opt_out": True}
    - budget_duration: Optional[str] - Budget is reset at the end of specified duration. If not set, budget is never reset. You can set duration as seconds ("30s"), minutes ("30m"), hours ("30h"), days ("30d").
    - tpm_limit: Optional[int] - [Not Implemented Yet] Specify tpm limit for a given customer (Tokens per minute)
    - rpm_limit: Optional[int] - [Not Implemented Yet] Specify rpm limit for a given customer (Requests per minute)
    - model_max_budget: Optional[dict] - [Not Implemented Yet] Specify max budget for a given model. Example: {"openai/gpt-4o-mini": {"max_budget": 100.0, "budget_duration": "1d"}}
    - max_parallel_requests: Optional[int] - [Not Implemented Yet] Specify max parallel requests for a given customer.
    - soft_budget: Optional[float] - [Not Implemented Yet] Get alerts when customer crosses given budget, doesn't block requests.
    - spend: Optional[float] - Specify initial spend for a given customer.
    - budget_reset_at: Optional[str] - Specify the date and time when the budget should be reset.
    
    
    - Allow specifying allowed regions 
    - Allow specifying default model

    Example curl:
    ```
    curl --location 'http://0.0.0.0:4000/customer/new'         --header 'Authorization: Bearer sk-1234'         --header 'Content-Type: application/json'         --data '{
            "user_id" : "ishaan-jaff-3",
            "allowed_region": "eu",
            "budget_id": "free_tier",
            "default_model": "azure/gpt-3.5-turbo-eu" <- all calls from this user, use this model? 
        }'

        # return end-user object
    ```

    NOTE: This used to be called `/end_user/new`, we will still be maintaining compatibility for /end_user/XXX for these endpoints
    r   )litellm_proxy_admin_name
llm_routerr   Nr   r   r   i  zmDefault Model not on proxy. Configure via `/model/new` or config.yaml. Default_model={}, proxy_model_names={}T)exclude_unset)
created_by
updated_by)r   rD   exclude_nonelitellm_budget_tabler   includez\litellm.proxy.management_endpoints.customer_endpoints.new_end_user(): Exception occured - {}z3Unique constraint failed on the fields: (`user_id`)z(Customer already exists, passed user_id=z. Please pass a new user_id.bad_requestr0   r   )messagetypecodeparamr   Internal Server Error()internal_errorr_   Noner   r\   r]   r_   r^   Internal Server Error, )#r    rQ   rR   r   r   r8   db_not_connected_errorr:   default_modelno_llm_routerget_model_namesformatsetrM   r"   litellm_budgettabler   
model_dumpr   r&   r'   rD   dictitemsrF   rG   rH   r#   r
   	exceptionProxyExceptionr2   rI   r	   HTTP_500_INTERNAL_SERVER_ERROR)r   rO   rQ   rR   r   new_end_user_obj_new_budgetbudget_recordr+   
_user_datakvend_user_records                r,   new_end_userrz      sN    t
  .EEKKL
 	
P
)!# ##%6%D%D%J%JK  ##:+E+E+GG# #  "Q  "X  "X ..J4N4N4P0Q"  "$ )."
O&3&6&6&J&J&Q&Q%00t0D&7&?&?&[C[&7&?&? '43	 'R ' ! -:,C,C[)^^',0NN[)YYDY1
$$&DAq(55::<<&' # '
 !. 0 0 E E L L!+T2 !M !
 

 7!  O#Wc!f<MNNO
  
&&jqqA	

 ACFJ B4<<.Plm"	  a' 8/Ec!fXQ-OP%a&1Qv/T/TU	  >*G-A6!!Wf-66	
 	
/
st   5LB H AG* 5G(6G* :A3H .3H !H"H 'L(G* *	H3HHH 	LC8LLLz/customer/info)r   r   response_modelz/end_user/infoz%End User ID in the request parameters)descriptionend_user_idc                 6  K   ddl m} |'t        ddt        j                  j
                  i      |j                  j                  j                  d| idd	i
       d{   }|t        dddj                  |       i      |j                  d	      S 7 6w)ae  
    Get information about an end-user. An `end_user` is a customer (external user) of the proxy.

    Parameters:
    - end_user_id (str, required): The unique identifier for the end-user

    Example curl:
    ```
    curl -X GET 'http://localhost:4000/customer/info?end_user_id=test-litellm-user-4'         -H 'Authorization: Bearer sk-1234'
    ```
    r   r   Nr   r   r   r   rX   Tr   rZ   r0   #End User Id={} does not exist in dbrV   )r    r   r   r8   rf   r:   r"   r#   
find_firstrj   rm   )r}   r   	user_infos      r,   end_user_infor   F  s     : 9.EEKKL
 	

 $&&;;FF+&1G0N G  I BII+VW
 	
 T22s   AB B!7Bz/customer/updatez/end_user/updatec                 .  K   ddl m} 	 | j                         }|t        d      i }|j	                         D ]  \  }}|	|g i dfvs|||<    |j
                  j                  j                  d| j                  iddi       d{   }|(t        d	d
dj                  | j                        i      t        d!i |j                         }|j                  }	i }
i }|j	                         D ]P  \  }}|t        j                  j!                         v r||
|<   |t        j                  j!                         v sL|||<   R |
r~|	A|j
                  j"                  j%                  |
ddi       d{   }|j&                  |d<   n;|j
                  j"                  j)                  d|	j&                  i|
       d{   }t+        j,                  d|        | j                  t/        | j                        dkD  r| j                  |d<   t+        j,                  d       |j
                  j                  j)                  d| j                  i|ddi       d{   }|t1        d| j                         t+        j,                  d|        |S t1        d| j                         7 #7 ;7 7 X# t        $ r}t+        j2                  dj                  t5        |                   t7        |t              rKt9        t;        |ddt5        |       d      dt;        |dd      t;        |dt<        j>                              t7        |t8              r|t9        d t5        |      z   dt;        |dd      t<        j>                        d}~ww xY ww)"a  
    Example curl 

    Parameters:
    - user_id: str
    - alias: Optional[str] = None  # human-friendly alias
    - blocked: bool = False  # allow/disallow requests for this end-user
    - max_budget: Optional[float] = None
    - budget_id: Optional[str] = None  # give either a budget_id or max_budget
    - allowed_model_region: Optional[AllowedModelRegion] = (
        None  # require all user requests to use models in this specific region
    )
    - default_model: Optional[str] = (
        None  # if no equivalent model in allowed region - default all requests to this model
    )

    Example curl:
    ```
    curl --location 'http://0.0.0.0:4000/customer/update'     --header 'Authorization: Bearer sk-1234'     --header 'Content-Type: application/json'     --data '{
        "user_id": "test-litellm-user-4",
        "budget_id": "paid_tier"
    }'

    See below for all params 
    ```
    r   r   NNot connected to DB!r   rX   Tr   r0   r   r   r   r#   rY   rD   r   z$/customer/update: Received data = %sz,In update customer, user_id condition block.)r   r   rZ   zEFailed updating customer data. User ID does not exist passed user_id=8received response from updating prisma client. response=&user_id is required, passed user_id = zDlitellm.proxy.proxy_server.update_end_user(): Exception occured - {}r   r`   ra   rb   r_   rc   r   rd   re   rE   ) r    r   jsonr&   ro   r"   r#   r   r   r   rj   LiteLLM_EndUserTablerm   rX   LiteLLM_BudgetTablerG   rH   rl   r   rD   r   r
   debuglen
ValueErrorrp   r'   r2   rq   rI   r	   rr   )r   rO   r   	data_jsonnon_default_valuesrw   rx   end_user_table_dataend_user_table_data_typedend_user_budget_tablebudget_table_dataupdate_end_user_table_databudget_table_data_recordresponser+   s                  r,   update_end_userr   w  s    Z 9m
))+	 233  OO%DAq}+ "
 )*"1% & %2$4$4$I$I$T$Tdll+6Ld5S %U %
 
 &BII$,,W  %9 %
!,,.%
!
 !: N N %'"&,,.DAq'4499;;'(!!$(55::<<01*1- / $, (**>>EE.9OQU8V F   ) -66 + (**>>EE*,A,K,KL. F   ) 	""#I4P<<#DLL(9A(=48LL&y1 &&'UV*--BBII $,,/6P[qswZx J  H  [\`\h\h[ij  !&&J8*U OEdll^TUUI
D   
&&RYYA	

 a' 8/Ec!fXQ-OP%a&1Qv/T/TU	  >*G-A6!!Wf-66	
 	

s   N7J6 J6 
?J6 	J,
B2J6 =7J6 4J/5A
J6 ?J2 BJ6 J47J6 NJ6 /J6 2J6 4J6 6	N?CNNNz/customer/deletez/end_user/deletec                   K   ddl m} 	 |t        d      t        j                  d|        | j
                  t        | j
                  t              rt        | j
                        dkD  r|j                  j                  j                  dd| j
                  ii       d{   }|t        d	| j
                         |t        | j
                        k7  r2t        d
| j
                   d| dt        | j
                         d      t        j                  d|        |dt        | j
                        z   dS t        d| j
                         7 # t        $ r}t        j                  dj                  t        |                   t        j                  t!        j"                                t        |t$              rKt'        t)        |ddt        |       d      dt)        |dd      t)        |dt*        j,                              t        |t&              r|t'        dt        |      z   dt)        |dd      t*        j,                        d}~ww xY ww)a  
    Delete multiple end-users.

    Parameters:
    - user_ids (List[str], required): The unique `user_id`s for the users to delete

    Example curl:
    ```
    curl --location 'http://0.0.0.0:4000/customer/delete'         --header 'Authorization: Bearer sk-1234'         --header 'Content-Type: application/json'         --data '{
            "user_ids" :["ishaan-jaff-5"]
    }'

    See below for all params 
    ```
    r   r   Nr   z$/customer/delete: Received data = %sr   in)r   zEFailed deleting customer data. User ID does not exist passed user_id=zIFailed deleting all customer data. User ID does not exist passed user_id=z
. Deleted z customers, passed z
 customersr   z)Successfully deleted customers with ids: )deleted_customersr\   r   zDlitellm.proxy.proxy_server.delete_end_user(): Exception occured - {}r   r`   ra   rb   r_   rc   r   rd   re   )r    r   r&   r
   r   r!   r2   r?   r   r"   r#   delete_manyr   r'   r   rj   	traceback
format_excr   rq   rI   r	   rr   )r   rO   r   r   r+   s        r,   delete_end_userr     sv    B 96
 233""#I4PMM%4==$/DMM"Q&*--BBNN 4"78 O  H  [\`\i\i[jk  3t}}-- _`d`m`m_nnx  zB  yC  CV  WZ  [_  [h  [h  Wi  Vj  jt  u  !&&J8*U &.Fdmm$%  Edmm_UVV).  
""RYYA	

 	""9#7#7#9:a' 8/Ec!fXQ-OP%a&1Qv/T/TU	  >*G-A6!!Wf-66	
 	
!
s=   IBE #E$BE >I?E 	I"C5IIIz/customer/listz/end_user/listhttp_requestc           	        K   ddl m} |j                  t        j                  k7  rE|j                  t        j
                  k7  r(t        dddj                  |j                        i      |'t        ddt        j                  j                  i      |j                  j                  j                  d	d
i       d{   }g }|D ]*  }|j                  t        di |j!                                , |S 7 7w)z
    [Admin-only] List all available customers

    Example curl:
    ```
    curl --location --request GET 'http://0.0.0.0:4000/customer/list'         --header 'Authorization: Bearer sk-1234'
    ```

    r   r   i  r   z&Admin-only endpoint. Your user role={}r   Nr0   rX   T)rZ   rE   )r    r   	user_roleLitellmUserRolesPROXY_ADMINPROXY_ADMIN_VIEW_ONLYr   rj   r8   rf   r:   r"   r#   	find_manyr%   r   rm   )r   rO   r   r   returned_responseitems         r,   list_end_userr   t  s     4 9 	##'7'C'CC''+;+Q+QQAHH%//
 	
 .EEKKL
 	

 #%%::DD'. E  H 57  !5!J8I!JK s   B=C9?C7 8C9)%__doc__r   typingr   r   fastapir   r   r   r   r	   r<   litellm._loggingr
   litellm.proxy._types$litellm.proxy.auth.user_api_key_authr   routerpost
BlockUsersr-   rA   NewCustomerRequestrF   rM   UserAPIKeyAuthrz   getr   Queryr'   r   UpdateCustomerRequestr   DeleteCustomerRequestr   r   rE   rN   r,   <module>r      s  	  !  F F  1 " B	 
	 +,-	   
	 +,-  
(G: (G(GV 
	 +,-	   
	 +,-  
08Z 0808f/ H=M4N ( 
	 +,-	   
	 +,-   )00A(BU

U
%U
U
p 
	 +,-'	   
	 +,-	   %w}};"3"3"3J 
	 +,-  
 
	 +,-	   )00A(BR	
R	%R	R	j 
	 +,-  
 
	 +,-	   )00A(BO	
O	%O	O	d 
	 +,-,-	   
	 +,-	   )00A(B**%**rN   