
    h                       d Z ddlZddlZddlZddlZddlmZmZ ddlmZm	Z	m
Z
mZmZmZmZ ddlZddlmZmZmZmZmZmZ ddl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*m+Z+m,Z,m-Z-m.Z.m/Z/m0Z0m1Z1m2Z2m3Z3m4Z4m5Z5m6Z6m7Z7m8Z8m9Z9m:Z:m;Z; dd	l<m=Z=m>Z>m?Z?m@Z@ dd
lAmBZB ddlCmDZDmEZEmFZFmGZG ddlHmIZI ddlJmKZK ddlLmMZM ddlNmOZOmPZP ddlQmRZRmSZSmTZT ddlUmVZV ddlWmXZX ddlYmZZZm[Z[m\Z\m]Z]m^Z^m_Z_  e       Z`deade;debfdZc	 ddeRde
ea   deea   de
e#   fdZddee*e$f   deede;defdeef
dZgd e$de;defd!eedeef
d"Zhe`j                  d#d$g eeB      ge$%      eP eeB       edd&'      fde*d(ede;d)eea   fd*              Zjde:d+eea   deRde;d,eadeea   fd-Zkde*deeR   deea   fd.Zld/e$d0e"d1eVdebfd2Zme`j                  d3d$g eeB      g4      eP eeB       edd&'      fde:d(ede;d)eea   fd5              Znd6eed7e$deefd8Zod9ee)e
e)   f   d:ebfd;ZpdeeR   de4d:ebfd<Zqde4d7e$fd=Zrde;d>e$ddfd?Zsde4d>e$deRde;d,eadee
e&   e
e#   f   fd@Ztde4d>e$dAe
e&   ddfdBZude4d>e$deRde;d,eadee$e
e&   e
e#   f   fdCZve`j                  dDd$g eeB      ge0%      eP eeB      fde4de;fdE              Zwd7e$de5deebe
e)   f   fdFZxe`j                  dGd$g eeB      g4      eP eeB      fde5de;fdH              Zye`j                  dId$g eeB      ge7%      eP eeB      fde6d(ede;fdJ              ZzdKe
e)   dLe0de
e^   fdMZ{e`j                  dNd$g eeB      ge[%      eP eeB      fdeZde;fdO              Z|e`j                  dPd$g eeB      g4      eP eeB       edd&'      fded(ede;d)eea   fdQ              Z}de;d e$fdRZ~dSe$d1eVde$fdTZdUeadeRdVe2de2fdWZe`j                  dXd$g eeB      g4      eP ej                  ddYZ       eeB      fd(edeade;fd[              Ze`j                  d\d$g eeB      g4      eP eeB      fded(ede;fd]              Ze`j                  d^d$g eeB      g4      eP eeB      fded(ede;fd_              Ze`j                  d`       eeB      e
e$   fd(ede;fda       Ze`j                  dbd$ge] eeB      gc       ej                  dddZ       ej                  ddeZ       ej                  ddfZ       ej                  ddgZ       ej                  dhdidhj       ej                  dkdldhdmn       ej                  ddoZ       ej                  dpdqZ       eeB      f	d(edeea   dreea   deea   dseea   dteduedveea   dweade;fdx       Ze`j                  dyd$g eeB      g4      eP ej                  dddZ      d eeB      fd(edeea   dreea   de;fdz              Z	 	 ddeRduedtedee
e$   ef   fd{Zd!eed|eaddfd}Ze`j                  d~d$g eeB      gddde
e$   ii       ej                  ddYZ       ej                  ddZ       ej                  dhdidhj       ej                  dddhdmn       eeB      fdeea   dseea   dteduede;f
d       Zde$de
ea   de
ea   fdZe`j                  dd$g eeB      g4      eP eeB      fde8d(ede;fd              Ze`j                  dd$g eeB      g4      eP eeB      fde9d(ede;fd              Ze`j                  dd$g eeB      g4      eP ej                  ddYZ       eeB      fdeade;de\fd              Ze`j                  dd$g eeB      g4       eeB      fde_d(ede;de$fd       Ze`j                  deXd$g      ddddddhdkd eeB      f	deea   deea   deea   deea   deea   dteduedeea   de;fd       Zy)za
TEAM MANAGEMENT

All /team management endpoints

/team/new
/team/info
/team/update
/team/delete
    N)datetimetimezone)AnyDictListOptionalTupleUnioncast)	APIRouterDependsHeaderHTTPExceptionRequeststatus)	BaseModel)verbose_proxy_logger) BlockTeamRequestCommonProxyErrorsDeleteTeamRequestLiteLLM_AuditLogs1LiteLLM_ManagementEndpoint_MetadataFields_PremiumLiteLLM_ModelTableLiteLLM_OrganizationTableLiteLLM_TeamMembershipLiteLLM_TeamTableLiteLLM_TeamTableCachedObjLiteLLM_UserTableLitellmTableNamesLitellmUserRolesMemberNewTeamRequestProxyErrorTypesProxyExceptionSpecialManagementEndpointEnumsSpecialModelNamesSpecialProxyStringsTeamAddMemberResponseTeamInfoResponseObjectTeamInfoResponseObjectTeamTableTeamListResponseObjectTeamMemberAddRequestTeamMemberDeleteRequestTeamMemberUpdateRequestTeamMemberUpdateResponseTeamModelAddRequestTeamModelDeleteRequestUpdateTeamRequestUserAPIKeyAuth) allowed_route_check_inside_routecan_org_access_modelget_team_objectget_user_object)user_api_key_auth)_is_user_team_admin_set_object_metadata_field_upsert_budget_and_membership_user_has_admin_view)get_daily_activity)&handle_update_object_permission_common)TeamMemberPermissionChecks)add_new_membermanagement_endpoint_wrapper)PrismaClient_premium_user_checkhandle_exception_on_proxy)Router)SpendAnalyticsPaginatedResponse)BulkTeamMemberAddRequestBulkTeamMemberAddResponse GetTeamMemberPermissionsResponseTeamListResponseTeamMemberAddResult"UpdateTeamMemberPermissionsRequestteam_iduser_api_key_dictreturnc                 t    t         j                  ydt         j                  v r| t         j                  d   v S y)NFavailable_teams)litellmdefault_internal_user_paramsrM   rN   s     m/var/www/Befach/backend/env/lib/python3.12/site-packages/litellm/proxy/management_endpoints/team_endpoints.py_is_available_teamrV   j   s9    ++3G@@@'>>?PQQQ    prisma_clientteam_idsuser_idc           	         K   dd|ii}|d|gi|d<   | j                   j                  j                  |ddi       d{   }g }|D ]*  }|j                  t	        di |j                                , |S 7 7w)	z)Get all team memberships for a given userrM   inNrZ   litellm_budget_tableTwhereinclude )dblitellm_teammembership	find_manyappendr   
model_dump)rX   rY   rZ   	where_objteam_membershipsreturned_tmtms          rU   get_all_team_membershipsrk   r   s     
 3<dH=M1NI $wi0	) +--DDNN'. O  
 13K1DBMMODE  s   =A9A7 8A9datanew_team_data_jsonteam_member_budgetc                   K   ddl m} ddlm} | j                  ?d| j                  j                  dd       dt        j                         j                   }n!d	t        j                         j                   } | ||| j                  |
      |       d{   }|j                  d      i |d<   |j                  |d   d<   |j                  dd       |S 7 @w)zAAllows admin to create 1 budget, that applies to all team membersr   BudgetNewRequest)
new_budgetNzteam- -z-budget-zteam-budget-)
max_budgetbudget_duration	budget_id
budget_objrN   metadatateam_member_budget_idrn   )litellm.proxy._typesrq   >litellm.proxy.management_endpoints.budget_management_endpointsrr   
team_aliasreplaceuuiduuid4hexrv   getrw   pop)rl   rm   rN   rn   rq   rr   rw   team_member_budget_tables           rU    _create_team_member_budget_tabler      s      6 "DOO++C56htzz|?O?O>PQ 	 #4::<#3#3"45	%/#) 00

 ,&   j)1)+:& 	!** z" d ' s   BCCAC
team_table
updated_kvc                   K   ddl m} ddlm} | j                  i | _        | j                  j                  d      }|xt        |t              rh | |||      |       d{   }t        j                  d|j                   d	|        |j                  d
      i |d
<   |j                  |d
   d<   nt        | |||       d{   }|j                  dd       |S 7 }7 w)zD
    Add budget if none exists

    If budget exists, update it
    r   rp   )update_budgetNr{   )rw   ru   rx   z"Updated team member budget table: z, with team_member_budget=rz   rl   rm   rN   rn   rn   )r|   rq   r}   r   rz   r   
isinstancestrr   inforw   r   r   )r   rN   rn   r   rq   r   r{   
budget_rows           rU    _upsert_team_member_budget_tabler      s
     6 " 
&//334KL(Z8Ms-S('/- 0
 

 	!!01E1E0FF`as`tu	
 >>*%-%'Jz":D:N:N
:67 <)/1	
 

 NN'.-

s%   A"C&$C"%A$C&	C$
C&$C&z	/team/newzteam management)tagsdependenciesresponse_modelzThe litellm-changed-by header enables tracking of actions performed by authorized users on behalf of other users, providing an audit trail for accountability)descriptionhttp_requestlitellm_changed_byc                   K   	 ddl m}m}m}m} |t        dddi      |j                  j                  j                          d{   }|r|j                  |      rt        d	d
      | j                  #t        t        j                               | _
        nE|j                  | j                  dd       d{   }	|	t        ddd| j                   di      |j                  |j                  t         j"                  k7  rz| j$                  N|j$                  B| j$                  |j$                  kD  r)t        ddd|j$                   d|j                   i      | j&                  N|j&                  B| j&                  |j&                  kD  r)t        ddd|j&                   d|j                   i      | j(                  N|j(                  B| j(                  |j(                  kD  r)t        ddd|j(                   d|j                   i      | j*                  `t-        |j*                        dkD  rH| j*                  D ]9  }
|
|j*                  vst        ddd|j*                   d|j.                   i       |j.                  cd}| j0                  D ]  }|j.                  |j.                  k(  sd}  |du r0| j0                  j3                  t5        d|j.                               d}| j6                  t9        | j6                  t:              rt=        t?        j@                  | j6                        |j.                  xs ||j.                  xs |      }|j                  jB                  jE                  i |j?                  d             d{   }|jF                  }tI        | |       d{   }| j?                         }| jJ                  !tM        | ||| jJ                         d{   }tO        d,i |||d}tP        D ]'  }tS        | |      tU        ||tS        | |              ) |jV                  dd!l,m-}  ||jV                  "      |_.        g }|j0                  |j0                  }g |_        |j_                  d      }|ja                  |#      }|j                  j                  jE                  |d$di%       d{   }tc        | j                  |&      }te        |||||'       d{    tf        jh                  du r|j?                  d      }t?        j@                  |t        (      }tk        jl                   |to        t        t        j                               tq        jr                  tt        jv                        |xs |j.                  xs ||jx                  tz        j|                  | j                  d)|d*	      +             	 |j_                         S 7 7 C7 f7 H7 7 17 # t~        $ r |j;                         cY S w xY w# t~        $ r}t        |      d}~ww xY ww)-u  
    Allow users to create a new team. Apply user permissions to their team.

    👉 [Detailed Doc on setting team budgets](https://docs.litellm.ai/docs/proxy/team_budgets)


    Parameters:
    - team_alias: Optional[str] - User defined team alias
    - team_id: Optional[str] - The team id of the user. If none passed, we'll generate it.
    - members_with_roles: List[{"role": "admin" or "user", "user_id": "<user-id>"}] - A list of users and their roles in the team. Get user_id when making a new user via `/user/new`.
    - team_member_permissions: Optional[List[str]] - A list of routes that non-admin team members can access. example: ["/key/generate", "/key/update", "/key/delete"]
    - metadata: Optional[dict] - Metadata for team, store information for team. Example metadata = {"extra_info": "some info"}
    - tpm_limit: Optional[int] - The TPM (Tokens Per Minute) limit for this team - all keys with this team_id will have at max this TPM limit
    - rpm_limit: Optional[int] - The RPM (Requests Per Minute) limit for this team - all keys associated with this team_id will have at max this RPM limit
    - max_budget: Optional[float] - The maximum budget allocated to the team - all keys for this team_id will have at max this max_budget
    - budget_duration: Optional[str] - The duration of the budget for the team. Doc [here](https://docs.litellm.ai/docs/proxy/team_budgets)
    - models: Optional[list] - A list of models associated with the team - all keys for this team_id will have at most, these models. If empty, assumes all models are allowed.
    - blocked: bool - Flag indicating if the team is blocked or not - will stop all calls from keys with this team_id.
    - members: Optional[List] - Control team members via `/team/member/add` and `/team/member/delete`.
    - tags: Optional[List[str]] - Tags for [tracking spend](https://litellm.vercel.app/docs/proxy/enterprise#tracking-spend-for-custom-tags) and/or doing [tag-based routing](https://litellm.vercel.app/docs/proxy/tag_routing).
    - organization_id: Optional[str] - The organization id of the team. Default is None. Create via `/organization/new`.
    - model_aliases: Optional[dict] - Model aliases for the team. [Docs](https://docs.litellm.ai/docs/proxy/team_based_routing#create-team-with-model-alias)
    - guardrails: Optional[List[str]] - Guardrails for the team. [Docs](https://docs.litellm.ai/docs/proxy/guardrails)
    - object_permission: Optional[LiteLLM_ObjectPermissionBase] - team-specific object permission. Example - {"vector_stores": ["vector_store_1", "vector_store_2"]}. IF null or {} then no object permission.
    - team_member_budget: Optional[float] - The maximum budget allocated to an individual team member.
    - team_member_key_duration: Optional[str] - The duration for a team member's key. e.g. "1d", "1w", "1mo"
    
    Returns:
    - team_id: (str) Unique team id - used for tracking spend across multiple keys for same team id.

    _deprecated_params:
    - admins: list - A list of user_id's for the admin role
    - users: list - A list of user_id's for the user role

    Example Request:
    ```
    curl --location 'http://0.0.0.0:4000/team/new'     --header 'Authorization: Bearer sk-1234'     --header 'Content-Type: application/json'     --data '{
      "team_alias": "my-new-team_2",
      "members_with_roles": [{"role": "admin", "user_id": "user-1234"},
        {"role": "user", "user_id": "user-2434"}]
    }'

    ```

     ```
    curl --location 'http://0.0.0.0:4000/team/new'     --header 'Authorization: Bearer sk-1234'     --header 'Content-Type: application/json'     --data '{
                "team_alias": "QA Prod Bot",
                "max_budget": 0.000000001,
                "budget_duration": "1d"
            }'
    ```
    r   )_license_checkcreate_audit_log_for_updatelitellm_proxy_admin_namerX   N  errorNo db connectedstatus_codedetail)
team_count  zOLicense is over limit. Please contact support@berri.ai to upgrade your license.teamfind_uniquerM   
table_name
query_type  z
Team id = z0 already exists. Please use a different team id.z/tpm limit higher than user max. User tpm limit=z. User role=z/rpm limit higher than user max. User rpm limit=z1max budget higher than user max. User max budget=z6Model not in allowed user models. User allowed models=z
. User id=FTadmin)rolerZ   model_aliases
created_by
updated_byexclude_none)rl   rX   r   )model_idobject_permission_id)object_data
field_namevalueget_budget_reset_timerv   db_datalitellm_model_table)rl   r`   )rM   memberrl   complete_team_datarX   rN   r   defaultcreated	id
updated_at
changed_bychanged_by_api_keyr   	object_idactionupdated_valuesbefore_valuerequest_datara   )Alitellm.proxy.proxy_serverr   r   r   rX   r   rb   litellm_teamtablecountis_team_count_over_limitrM   r   r   r   get_data	user_roler    PROXY_ADMIN	tpm_limit	rpm_limitru   modelslenrZ   members_with_rolesre   r!   r   r   dictr   jsondumpslitellm_modeltablecreater   _set_object_permissionrn   r   r   r   getattrr:   rv   )litellm.proxy.common_utils.timezone_utilsr   budget_reset_atrf   jsonify_team_objectr,   _add_team_members_to_teamrR   store_audit_logsasynciocreate_taskr   r   nowr   utcapi_keyr   TEAM_TABLE_NAME	ExceptionrD   )rl   r   rN   r   r   r   r   rX   total_teams_existing_team_idmcreating_user_in_listr   	_model_idr   
model_dictr   	data_jsonr   fieldr   r   complete_team_data_dictteam_rowteam_member_add_request_updated_valueses                              rU   new_teamr      s    TQ+	
 	
  CBS8TUU *,,>>DDFF>BB" C 
  h 
 <<tzz|,DL '4&<&<M '= ' ! !,# #:dll^;k!l  ''/ **.>.J.JJ *%//;NN%6%@%@@# ##RSdSnSnRoo{  }N  }X  }X  |Y  "Z  *%//;NN%6%@%@@# ##RSdSnSnRoo{  }N  }X  }X  |Y  "Z  +%00<OO&7&B&BB# ##TUfUqUqTrr~  @Q  @[  @[  \  "]  {{&3/@/G/G+H1+LA 1 8 88+(+ '+absbzbza{  |F  GX  G`  G`  Fa  *b$  % $$0$)!11>>%6%>%>>,0) 2 %-''..1B1J1JK
 	)j9K9KT.R!3"jj););<,44P8P,44P8P"
  -//BBII>%***=>  J #I &<'&
  
 IIK	"".>#,"3#'#:#:	 I / 

!5
 GEtU#/* 2$!$. G --9W1F 2 B B2.
 ,.00<!3!F!F461"4"?"?T"?"R"/"C"C+ #D #
 -:,<,<,N,N,U,U(*D1 -V -
 '
 #7LL%#
 ((''/%=
 	
 	
 ##t+05545HO"jj#FO+!2tzz|,#+<<#=#5 $4,44$43+<+D+D#4#D#D"&,,('6%)"$	#&&((C G!` 
T'
	
D  	#==?"	# +'**+s   YAX2 W>	A5X2 >X?FX2 A X2 =C!X2 X X2 ?X <X2 <X
=)X2 'B5X2 X.X2 XC!X2 .X =Y>X2 X2 X2 X2 
X2 X2 X2 X/,X2 -Y.X//X2 2	Y;YYYr   r   c                 D  K   |}| j                   t        | j                   t              rt        t	        j
                  | j                         |j                  xs ||j                  xs |      }|A|j                  j                  j                  i |j	                  d             d{   }nX|j                  j                  j                  d|ii |j	                  d      i |j	                  d      d       d{   }|j                  }|S 7 k7 w)	z4
    Upsert model table and return the model id
    Nr   Tr   rl   r   )updater   r_   rl   )r   r   r   r   r   r   rZ   rb   r   r   upsertr   )rl   r   rX   rN   r   r   r   r   s           rU   _update_model_tabler     s)     I%*T5G5G*N/**T%7%78(00L4L(00L4L

 ,//BBIIC*//T/BC  J   J  -//BBIIX&L!3!8!8d!8!KLL!3!8!8d!8!KL  J   J MM	s%   B.D 0D1AD 	D
D D c                    K   |y| j                   V|j                  j                  j                  | j                   j	                  d             d{   }| ` |j
                  S y7 w)z
    Creates the LiteLLM_ObjectPermissionTable record for the team.
    - Handles permissions for vector stores and mcp servers.

    Returns the object_permission_id if created, otherwise None.
    NTr   r   )object_permissionrb   litellm_objectpermissiontabler   rf   r   )rl   rX   created_object_permissions      rU   r   r   &  sz      )""@@GG++66D6I H   	"
 "(===s   AA+A)A+r   organization
llm_routerc           	         | j                   |j                   k(  ryt        |j                        dkD  ryt        j                  j
                  |j                  v rnR| j                  t        | j                        dk(  rt        dddi      | j                  D ]  }t        |||        | j                  ry|j                  rm|j                  j                  rW| j                  |j                  j                  kD  r4t        ddd| j                   d	|j                  j                   d
i      | j                  D cg c]  }|j                   }}|j                  r$|j                  D cg c]  }|j                   c}ng }|D cg c]%  }||vr|t        j                  j
                  k7  r|' }}t        |      dkD  rt        ddd| di      | j                  ry|j                  rm|j                  j                  rW| j                  |j                  j                  kD  r4t        ddd| j                   d|j                  j                   d
i      | j                   ry|j                  rm|j                  j                   rW| j                   |j                  j                   kD  r4t        ddd| j                    d|j                  j                    d
i      yc c}w c c}w c c}w )a2  
    Validate that a team can be moved to an organization.

    - The org must have access to the team's models
    - The team budget cannot be greater than the org max_budget
    - The team's user_id must be a member of the org
    - The team's tpm/rpm limit must be less than the org's tpm/rpm limit
    Tr   r   r   zeCannot move team to organization. Team has access to all proxy models, but the organization does not.r   )model
org_objectr  z6Cannot move team to organization. Team has max_budget z4 that is greater than the organization's max_budget .z3Cannot move team to organization. Team has user_id z* that is not a member of the organization.z5Cannot move team to organization. Team has tpm_limit z3 that is greater than the organization's tpm_limit z5Cannot move team to organization. Team has rpm_limit z3 that is greater than the organization's rpm_limit )organization_idr   r   r&   all_proxy_modelsr   r   r5   ru   r]   r   rZ   usersr'   default_user_idr   r   )r   r  r  r  r   team_membersorg_members
not_in_orgs           rU   validate_team_org_changer  >  sM    |;;; <!#--33|7J7JJ[[ C$4$9  E  $+) % 	----88OOl??JJJQRVRaRaQb  cW  Xd  Xy  Xy  XD  XD  WE  EF  G
 	
 (,'>'>?!AII?L?=I=O=Ol&8&891999UWK KA)<)L)L)R)R$R 	
J 
 :Nzl  [E  F
 	
 	----77NN\>>HHHPQUQ_Q_P`  aT  Ua  Uv  Uv  U@  U@  TA  AB  C
 	
 	----77NN\>>HHHPQUQ_Q_P`  aT  Ua  Uv  Uv  U@  U@  TA  AB  C
 	
 Q @9s   ?K".K'
*K,z/team/update)r   r   c                 	  K   ddl m} ddlm}m}m}m}m}	m}
 |'t        ddt        j                  j                  i      | j                  t        ddd	i      t        j                  d
|        |j                   j"                  j%                  d| j                  i       d{   }|t        ddd| j                   i      | j&                  t)        | j&                        dkD  r|'t        ddt        j*                  j                  i      |j                   j,                  j%                  d| j&                  iddd       d{   }|t        ddd| j&                   i      t/        t1        d,i |j3                         t5        d,i |j3                         |       n+| j&                  t)        | j&                        dk(  rd| _        | j7                  d      }| j8                  ddlm}  || j8                        }||d<   | j>                  "tA        ||| j>                  |       d{   }n|jC                  dd       | jD                  tG        ||       d{   }tH        }|D ]  }||v s||   tK        ||        d|v r:|jC                  d       tM        | |jN                  |||       d{   }|||d<   |jQ                  |       }|j                   j"                  jS                  d| j                  i|d!di"       d{   }||j                  t        ddd#jU                  |      i      t        jV                  d$|j                          ||j                  tY        d,i |j3                         |
|	%       d{    tZ        j\                  du r|j7                  d&      }t7        j^                  |t`        '      }t7        j^                  |t`        '      }tc        jd                   |tg        ta        ti        jj                               tm        jn                  tp        jr                        |xs |jt                  xs ||jv                  tx        jz                  | j                  d(||)	      *             |j                  |d+S 7 7 f7 z7 I7 7 7 w)-aZ  
    Use `/team/member_add` AND `/team/member/delete` to add/remove new team members

    You can now update team budget / rate limits via /team/update

    Parameters:
    - team_id: str - The team id of the user. Required param.
    - team_alias: Optional[str] - User defined team alias
    - team_member_permissions: Optional[List[str]] - A list of routes that non-admin team members can access. example: ["/key/generate", "/key/update", "/key/delete"]
    - metadata: Optional[dict] - Metadata for team, store information for team. Example metadata = {"team": "core-infra", "app": "app2", "email": "ishaan@berri.ai" }
    - tpm_limit: Optional[int] - The TPM (Tokens Per Minute) limit for this team - all keys with this team_id will have at max this TPM limit
    - rpm_limit: Optional[int] - The RPM (Requests Per Minute) limit for this team - all keys associated with this team_id will have at max this RPM limit
    - max_budget: Optional[float] - The maximum budget allocated to the team - all keys for this team_id will have at max this max_budget
    - budget_duration: Optional[str] - The duration of the budget for the team. Doc [here](https://docs.litellm.ai/docs/proxy/team_budgets)
    - models: Optional[list] - A list of models associated with the team - all keys for this team_id will have at most, these models. If empty, assumes all models are allowed.
    - blocked: bool - Flag indicating if the team is blocked or not - will stop all calls from keys with this team_id.
    - tags: Optional[List[str]] - Tags for [tracking spend](https://litellm.vercel.app/docs/proxy/enterprise#tracking-spend-for-custom-tags) and/or doing [tag-based routing](https://litellm.vercel.app/docs/proxy/tag_routing).
    - organization_id: Optional[str] - The organization id of the team. Default is None. Create via `/organization/new`.
    - model_aliases: Optional[dict] - Model aliases for the team. [Docs](https://docs.litellm.ai/docs/proxy/team_based_routing#create-team-with-model-alias)
    - guardrails: Optional[List[str]] - Guardrails for the team. [Docs](https://docs.litellm.ai/docs/proxy/guardrails)
    - object_permission: Optional[LiteLLM_ObjectPermissionBase] - team-specific object permission. Example - {"vector_stores": ["vector_store_1", "vector_store_2"]}. IF null or {} then no object permission.
    - team_member_budget: Optional[float] - The maximum budget allocated to an individual team member.
    - team_member_key_duration: Optional[str] - The duration for a team member's key. e.g. "1d", "1w", "1mo"
    Example - update team TPM Limit

    ```
    curl --location 'http://0.0.0.0:4000/team/update'     --header 'Authorization: Bearer sk-1234'     --header 'Content-Type: application/json'     --data-raw '{
        "team_id": "8d916b1c-510d-4894-a334-1c16a93344f5",
        "tpm_limit": 100
    }'
    ```

    Example - Update Team `max_budget` budget
    ```
    curl --location 'http://0.0.0.0:4000/team/update'     --header 'Authorization: Bearer sk-1234'     --header 'Content-Type: application/json'     --data-raw '{
        "team_id": "8d916b1c-510d-4894-a334-1c16a93344f5",
        "max_budget": 10
    }'
    ```
    r   )_cache_team_object)r   r   r  rX   proxy_logging_objuser_api_key_cacheNr   r   r   r   No team id passed inz/team/update - %srM   r_     Team not found, passed team_id=r
  T)r]   r  r^   z/Organization not found, passed organization_id=)r   r  r  )exclude_unsetr   r   r   )r   r   rn   rN   rn   )r   existing_team_row)r   r   r   )rl   r   rX   rN   r   r   r   r   )r_   rl   r`   zTeam doesn't exist. Got={}z$Successfully updated team - %s, info)rM   r   r  r  r   r   updatedr   r   )rM   rl   ra   )>litellm.proxy.auth.auth_checksr  r   r   r   r  rX   r  r  r   r   db_not_connected_errorr   rM   r   debugrb   r   r   r
  r   no_llm_routerlitellm_organizationtabler  r   rf   r   r   rv   r   r   rn   r   r   r  handle_update_object_permissionr   _update_team_metadata_fieldr   r   r   r   formatr   r   rR   r   r   r   r   r   r   r   r   r   r   r   r   rZ   r   r   r   )rl   r   rN   r   r  r   r   r  rX   r  r  r  organization_rowr   r   reset_at_team_metadata_fieldsr   r   r   _before_value_after_values                         rU   update_teamr*    s    v B  .EEKKL
 	

 ||W>T4UVV2D9+..@@LL$,,' M    >t||nMN
 	
 	(S1E1E-F-J2C2Q2Q2W2W(X  "/!1!1!K!K!W!W$d&:&:;-1DA "X "
 
 #NtOcOcNde  	!"D%6%A%A%CD2S5E5P5P5RS!	

 
			)c$2F2F.G1.L#.J 'S(9M9MN )1
$%*;(!#66/	
 

 	+T2 ): /
 

 N&J:e#4#@'%  ' *$'-&//'/%=
 
	  %.Jz"22:2FJ0077dll+*D1 8 
 	
  8++39@@JK
 	

 DhFVFVW
  -F0C0C0EF-+	   4')..D.A

=#> JJz3?'.4::<('||HLL91  0(00 0/'8'@'@0@@"ll$#/!.	
$  ''::K"
@

 
	
s   B&S	(R4)B(S	R7C.S	 R:3S	4R=5S		S	AS	S AS	'S(B S	(S)DS	7S	:S	=S	 S	S	S	r   r  c                    K   ddl m} t        | |j                  |       d{   }||| d<   t	        j
                  d|        | S 7 %w)a  
    Handle the update of object permission for a team.

    - IF there's no object_permission_id, then create a new entry in LiteLLM_ObjectPermissionTable
    - IF there's an object_permission_id, then update the entry in LiteLLM_ObjectPermissionTable
    r   rX   )r   existing_object_permission_idrX   Nr   zupdated object_permission_id: )r   rX   r>   r   r   r  )r   r  rX   r   s       rU   r"  r"  s  sg      9 "H&7&L&L#"  ',@	()"",-A,BC	
 s   "AA
&Ar   premium_userc                 D   t        | t              r:| j                  dk(  r+|dur&t        dt        j
                  j                         y t        | t              rF| D ]@  }|j                  dk(  s|dust        d| dt        j
                  j                   d       y y )Nr   Tz,Assigning team admins is a premium feature. z0Assigning team admins is a premium feature. Got=z. )r   r!   r   
ValueErrorr   not_premium_userr   r   )r   r.  r   s      rU   _check_team_member_admin_addr2    s     &&!fkkW&<t#>?P?a?a?g?g>hi  $ 
FD	!Avv t+$J1#RPaPrPrPxPxOyy{|   
"rW   c                    | t        dddi      |j                  t        dddi      |j                  t        dddi      	 t        |j                  |       y # t        $ r}t        ddt        |      i      d }~ww xY w)	Nr   r   r   r   r   r  zNo member/members passed in)r   r.  )r   rM   r   r2  r   r   )rX   rl   r.  r   s       rU   team_call_validation_checksr4    s    
 W>O4PQQ||W>T4UVV{{W.K$L
 	
G$;;%	
  GWc!f4EFFGs   	A! !	B*BBc                    g dt         ffd}t        | j                  t               r || j                         n3t        | j                  t              r| j                  D ]
  } ||        t        | j                  t              rKt              t        | j                        k(  r*t        dj                   t        j                  dd      t        | j                  t               rft              dk(  rXt        d| j                  j                   d| j                  j                   d	j                   t        j                  dd      t              d
kD  r&t        j                  dj                   d        yy)z
    Check if a member already exists in the team.
    This check is done BEFORE we create/fetch the user, so it only prevents
    obvious duplicates where both user_id and user_email match exactly.
    r   c                 (   | j                   <j                  D ]-  }|j                   | j                   k(  sj                  |        / | j                  =j                  D ]-  }|j                  | j                  k(  sj                  |        / y y N)rZ   r   re   
user_email)r   existing_memberr  invalid_team_memberss     rU   _check_member_duplicationzDteam_member_add_duplication_check.<locals>._check_member_duplication  s    >>%#4#G#G"**fnn<(//7 $H
 (#4#G#G"--1B1BB(//7 $H )rW   z0All users are already in team. Existing members=400messagetypeparamcode   z&User already in team. Member: user_id=z, user_email=z. Existing members=r   z1Some users are already in team. Existing members=z. Duplicate members=N)r!   r   r   r   listr   r$   r   r#   team_member_already_in_teamrZ   r8  r   r   )rl   r  r;  r   r:  s    `  @rU   !team_member_add_duplication_checkrE    s}    
8& 
8 $++v&!$++.	DKK	&A%a(  $++t$-A)Bc$++FV)VFGXGkGkFlm <<	
 	
 
DKK	(S1E-F!-K<T[[=P=P<QQ^_c_j_j_u_u^v  wJ  K\  Ko  Ko  Jp  q <<	
 	
 
!	"Q	&!!?@Q@d@d?eey  {O  zP  Q	
 
'rW   r   c                   K   t        | d      rw| j                  t        j                  j                  k7  rOt        | |      sAt        |j                  |       s)t        dddj                  d|j                        i      y	y	y	y	w)
z;Validate if user has permission to add members to the team.r   rN   team_objrT   r   r   JCall not allowed. User not proxy admin OR team admin. route={}, team_id={}/team/member_addr   N)
hasattrr   r    r   r   r9   rV   rM   r   r$  rN   r   s     rU   %_validate_team_member_add_permissionsrM    s      	!;/''+;+G+G+M+MM#/:L
 #&../

 ell&&..
 	


 N 	0s   BBc                   K   g }g }|j                   |j                   j                  d      nd}t        | j                  t              rd	 t        | j                  | j                  |||| j                  |       d{   \  }}	|j                  |       |	|j                  |	       ||fS t        | j                  t              rh| j                  D ]Y  }	 t        || j                  |||| j                  |       d{   \  }}	|j                  |       |	I|j                  |	       [ ||fS 7 # t        $ rB}
t        dddj                  | j                  | j                  t        |
            i      d}
~
ww xY w7 # t        $ r8}
t        dddj                  || j                  t        |
            i      d}
~
ww xY ww)z!Process and add new team members.Nr{   )
new_membermax_budget_in_teamrX   rN   r   rM   default_team_budget_idr   r   z6Unable to add user - {}, to team - {}, for reason - {}r   )rz   r   r   r   r!   r@   rP  rM   r   r   r$  r   re   r   )rl   r   rX   rN   r   updated_usersupdated_team_membershipsrQ  updated_user
updated_tmr   r   s               rU   _process_team_membersrV  	  s     .0M=? &&2 	##''(?@  $++v&	-;;;#'#:#:+"3)A'=. ($L*$ 	\*!$++J74 2223 
DKK	&A1? '+'>'>"/&7-E LL+A2 ,(j$   .%(//
;- 0 222](  	U\\T\\3q6 	,  # #!Y!`!`t||SV" sy   AG
3D6 >D4?D6 AG
)FFF	G
G
4D6 6	F?=E<<FG
F	G3GGG
rR  c                 *  K   t        | j                  t              r| j                  j                         }|j                  K|j
                  ?|D ]:  }|j
                  |j
                  |j
                  k(  s*|j                  |_        < d}|j                  D ]Q  }|j                  |j                  |j                  k(  s'|j
                  5|j
                  |j
                  k(  sOd} n |s|j                  j                  |       yyt        | j                  t              r| j                  D ]  }|j                  K|j
                  ?|D ]:  }|j
                  |j
                  |j
                  k(  s*|j                  |_        < d}|j                  D ]Q  }|j                  |j                  |j                  k(  s'|j
                  5|j
                  |j
                  k(  sOd} n |r|j                  j                  |        yyw)z*Update the team's members_with_roles list.NFT)	r   r   r!   
model_copyrZ   r8  r   re   r   )rl   r   rR  rO  usermember_already_existsr9  nms           rU   _update_team_members_listr\  M  s     $++v&[[++-
 %**?*?*K%OO/:+@+@@)-J& & !&1DDO"".#++z/A/AA%%1#..*2G2GG(,%  E %1188D % 
DKK	&++Bzz!bmm&?)D2t"--7W%)\\
 *
 %*!#5#H#HJJ*/F/F"**/TMM-'22bmmC,0) $I )"55<<R@'  
's?   AH!H;AHH+A6H"H<AHH,H4Hc                 z  K   t        | ||||       d{   \  }}t        | ||       d{    |j                  D cg c]  }|j                          }}|j                  j
                  j                  d| j                  idt        j                  |      i       d{   }	|	||fS 7 7 c c}w 7 w)zAdd team members to the team.r   N)rl   r   rR  rM   r   r   )
rV  r\  r   rf   rb   r   r   rM   r   r   )
rl   r   rX   rN   r   rR  rS  r   _db_team_membersupdated_teams
             rU   r   r     s      5J-#+!95 /+M+ $-#   1C0U0UV1VV&));;BB$,,'"DJJ/?$@A C  L
 (@@@-/ Ws>   B;B0B;B2B;B4AB;&B9'
B;2B;4B;rJ  c           
      D  K   ddl m}m}m}m}m} 	 t        || |       t        t        |      }t        | j                  ||d|dd       d{   }|t        dd	d
t        | dd       i      t        di |j                         }	t        | |	       t!        ||	       d{    t#        | |	|||       d{   \  }
}}|
t        dd	d| j                   di      t%        di |
j                         ||dS # t        $ r}|d}~ww xY w7 7 r7 \w)a  
    Add new members (either via user_email or user_id) to a team

    If user doesn't exist, new user row will also be added to User Table

    Only proxy_admin or admin of team, allowed to access this endpoint.
    ```

    curl -X POST 'http://0.0.0.0:4000/team/member_add'     -H 'Authorization: Bearer sk-1234'     -H 'Content-Type: application/json'     -d '{"team_id": "45e3e396-ee08-4a61-a88e-16b3ce7e0849", "member": {"role": "user", "user_id": "krrish247652@berri.ai"}}'

    ```
    r   )r   r.  rX   r  r  )rX   rl   r.  NFTrM   rX   r  parent_otel_spanr  check_cache_onlycheck_db_onlyr  r   Team not found for team_id=rM   r   )rl   r  rL  r   zTeam with id z
 not found)rR  rS  ra   )r   r   r.  rX   r  r  r4  r   r   rB   r6   rM   r   r   rf   rE  rM  r   r(   )rl   rN   r   r.  rX   r  r  r   r  r   r_  rR  rS  s                rU   team_member_addrf    s~    4 #'%	
 }5M-#-+   6wtYPT7U6VW
 	
 +L->-I-I-KL%, 0+-   (1'/%=
 	
 :L-!9 Wdll^:.V$W
 	
 ! 

!
!
##!9 e  
2	
sY   D D /D DAD )D*D DAD 	DDDD D D c                 &   d}g }| j                   D ]{  }|j                  (|j                  |j                  |j                  k(  rd}7|j                  (|j                  |j                  |j                  k(  rd}k|j                  |       } ||fS )z+Cleanup members_with_roles list for a team.FT)r   rZ   r8  re   )r  rl   is_member_in_teamnew_team_membersr   s        rU   _cleanup_members_with_rolesrj  	  s    
 %'11LL$		%		) $OO'(1<</ $" 2  ...rW   /team/member_deletec                   K   ddl m} |t        dddi      | j                  t        ddd	i      | j                  | j
                  t        ddd
i      |j                  j                  j                  d| j                  i       d{   }|(t        dddj                  | j                        i      t        di |j                         }|j                  t        j                  j                  k7  r6t!        ||      s)t        dddj                  d|j                        i      t#        ||       \  }}|st        dddi      ||_        |D cg c]  }|j                          }}|j                  j                  j'                  d| j                  idt)        j*                  |      i       d{   }	i }
| j                  | j                  |
d<   n| j
                  | j
                  |
d<   |j                  j,                  j/                  |
       d{   }|t1        |t2              rt5        |      dkD  r|D ]  }g }| j                  |j6                  v s|j6                  }|j9                  | j                         |j                  j,                  j'                  d|j                  idd|ii       d{     |S 7 Kc c}w 7 7 7 w)a  
    [BETA]

    delete members (either via user_email or user_id) from a team

    If user doesn't exist, an exception will be raised
    ```
    curl -X POST 'http://0.0.0.0:8000/team/member_delete' 
    -H 'Authorization: Bearer sk-1234' 
    -H 'Content-Type: application/json' 
    -d '{
        "team_id": "45e3e396-ee08-4a61-a88e-16b3ce7e0849",
        "user_id": "krrish247652@berri.ai"
    }'
    ```
    r   r,  Nr   r   r   r   r   r  2Either user_id or user_email needs to be passed inrM   r  Team id={} does not exist in dbrG  r   rI  rk  )r  rl   zUser not found in teamr   r   rZ   r8  teamssetra   )r   rX   r   rM   rZ   r8  rb   r   r   r$  r   rf   r   r    r   r   r9   rj  r   r   r   r   litellm_usertablerd   r   rC  r   ro  remove)rl   rN   rX   _existing_team_rowr  rh  ri  r   _db_new_team_members_key_valexisting_user_rowsexisting_user	team_lists                 rU   team_member_deleterz  #  s    : 9W>O4PQQ||W>T4UVV|| 7QR
 	

  -//AAMM$,,'  N    !>EEdllST
 	
 *L,>,I,I,KL
 	##'7'C'C'I'II#/:K
 ell)+<+D+D
 	
 +F++''
 W>V4WXX+;(@P'Q1'Q'Q0077t||
 #DJJ/C$DE	 8  	A G||!\\			$ $,//AAKK  L    %%t,5G1H11L/MI||}222)//	  .#&&88??!=#8#8 "E9#56	 @    0 UN (R	s_   BK+KCK+"K9AK+K$A&K+-K'.AK+2A!K+K)	K+K+'K+)K+z/team/member_updatec           	        K   ddl m}m} |t        dddi      | j                  t        ddd	i      | j
                  d
k(  r|st        dd      | j                  | j                  t        dddi      |j                  j                  j                  d| j                  i       d{   }|(t        dddj                  | j                        i      t        di |j                         }|j                  t        j                   j"                  k7  r6t%        ||      s)t        dddj                  d|j                        i      t'        || j                  |       d{   }|d   }d}	| j                  | j                  }	nT| j                  H|d   j(                  D ]6  }
|
j                  |
j                  | j                  k(  s*|
j                  }	 n |	t        dddj                  |       i      d}|d   D ]  }|j                  |	k(  s|j*                  } n |j                  j-                         4 d{   }t/        || j                  |	| j0                  ||       d{    ddd      d{    | j
                  g }|j(                  D ]l  }
|
j                  |	k(  rJ|j3                  t5        |
j                  | j
                  | j                  xs |
j                               \|j3                  |
       n ||_        |D cg c]  }|j                          }}|j                  j                  j7                  d| j                  idt9        j:                  |      i       d{    t=        | j                  |	| j                  | j0                        S 7 7 O7 r7 H7 ;# 1 d{  7  sw Y   LxY wc c}w 7 [w)zE
    [BETA]

    Update team member budgets and team member role
    r   )r.  rX   Nr   r   r   r   r   r  r   a
  Assigning team admins is a premium feature. You must be a LiteLLM Enterprise user to use this feature. If you have a license please set `LITELLM_LICENSE` in your env. Get a 7 day trial key here: https://www.litellm.ai/#trial. Pricing: https://www.litellm.ai/#pricingrm  rM   r  rn  rG  r   rI  rk  )r   rM   rN   	team_infoz,User id doesn't exist in team table. Data={}rh   )txrM   rZ   ru   existing_budget_idrN   )rZ   r   r8  r   r   )rM   rZ   r8  rP  ra   )r   r.  rX   r   rM   r   rZ   r8  rb   r   r   r$  r   rf   r   r    r   r   r9   r|  r   rw   r}  r;   rP  re   r!   r   r   r   r/   )rl   r   rN   r.  rX   rs  r  returned_team_infor   received_user_idr   identified_budget_idrj   r}  r  r   r^  s                    rU   team_member_updater    s    " GW>O4PQQ||W>T4UVVyyGL `
 	
 || 7QR
 	

  -//AAMM$,,'  N    !>EEdllST
 	
 *L,>,I,I,KL
 	##'7'C'C'I'II#/:K
 ell)+<+D+D
 	
 8A!+8 2 $K0J '+||<<		$(5HHF  ,1B1Bdoo1U#)>>  I
 GNNtT
 	
 +/ !34::))#%<<  5 ""$ 
 
+LL$..3/
 	
 	

 
 yy%' 33F~~!11## &!YY#'??#Gf6G6G ##F+ 4 )5
%@L'M1'M'M0077dll+&

3C(DE 8 
 	
 	

 $ ??22	 }82B
	

 
 
 
6 (N	
s   B/O)1N=2B?O)1O 2AO)O)AO)$-O)OO))O>O?OO)O	BO)'O">AO)O'2O) O)O)O	O)OOOO)membersresponsec           
         g }| D ]  }d}|j                   D ]_  }|j                  r|j                  |j                  k(  s'|j                  s5|j                  |j                  k(  sO|j                         } n d}|j                  D ]:  }|j                  s|j                  |j                  k(  s*|j                         } n |j                  t        |j                  |j                  d||              |S )zS
    Convert TeamAddMemberResponse into individual TeamMemberAddResult objects
    NT)rZ   r8  successrT  updated_team_membership)rR  rZ   r8  rf   rS  re   rK   )r  r  resultsr   rT  rY  r  rj   s           rU   _create_results_from_responser  &  s     *,G**D4<<6>>#A!!doo9J9J&J#0 + #'33B~~"**">*,--/' 4
 	!,,)(?	
# 6 NrW   z/team/bulk_member_addc           
        K   ddl m} ddlm} |#t	        dd|j
                  j                  i      | j                  re|j                  j                  j                  dd	i
       d{   }|D cg c]$  }t        |j                  |j                  d      & c}| _        | j                  st	        dddi      d}t        | j                        |kD  rt	        ddd| di      	 t!        t#        | j$                  | j                  | j&                        |       d{   }t)        | j                  |      }t+        | j$                  |t        | j                        t        |      d|j-                               S 7 c c}w 7 g# t.        $ r}	t1        j2                  |	       t5        |	      }
| j                  D cg c]%  }t7        |j                  |j                  d|
      ' nc c}w }}t+        | j$                  |t        | j                        dt        | j                        d      cY d}	~	S d}	~	ww xY ww)a"  
    Bulk add multiple members to a team at once.
    
    This endpoint reuses the same logic as /team/member_add but provides a bulk-friendly response format.
    
    Parameters:
    - team_id: str - The ID of the team to add members to
    - members: List[Member] - List of members to add to the team
    - all_users: Optional[bool] - Flag to add all users on Proxy to the team
    - max_budget_in_team: Optional[float] - Maximum budget allocated to each user within the team
    
    Returns:
    - results: List of individual member addition results
    - total_requested: Total number of members requested for addition
    - successful_additions: Number of successful additions  
    - failed_additions: Number of failed additions
    - updated_team: The updated team object
    
    Example request:
    ```bash
    curl --location 'http://0.0.0.0:4000/team/bulk_member_add'     --header 'Authorization: Bearer sk-1234'     --header 'Content-Type: application/json'     --data '{
        "team_id": "team-1234",
        "members": [
            {
                "user_id": "user1",
                "role": "user"
            },
            {
                "user_email": "user2@example.com",
                "role": "admin"
            }
        ],
        "max_budget_in_team": 100.0
    }'
    ```
    r   )r   r,  Nr   r   r   
created_atdesc)orderrY  )rZ   r8  r   r   zAt least one member is requiredzMaximum z members can be added at once)rM   r   rP  rl   rN   )rM   r  total_requestedsuccessful_additionsfailed_additionsr_  F)rZ   r8  r  r   )r|   r   r   rX   r   r  r   	all_usersrb   rq  rd   r!   rZ   r8  r  r   rf  r,   rM   rP  r  rH   rf   r   r   	exceptionr   rK   )rl   rN   r   rX   all_users_in_dbrY  MAX_BATCH_SIZEr  r  r   error_messager   s               rU   bulk_team_member_addr  M  s:    d 78.EEKKL
 	

 ~~ - 0 0 B B L L( !M !
 
 (
  ??
 <<>?
 	
 N
4<<>)x'77TUV
 	

,
(%||#'#:#:
 0
 
 0hG(LL-!$W!,,.
 	
Q

2
*  
&&q)A ,,
   !,,#	
 
 
 )LL-!" .
 	

su   A)I	+F,I	4)FAI	.:F (F)AF I	I	F 	I.I	*G43AI;I<I	II	z/team/deletec                   K   ddl m}m}m} |t	        dddi      | j
                  t	        ddd	i      g }| j
                  D ]f  }	 |j                  j                  j                  d
|i       d{   }	|	t        	 t        di |	j                         }
|j                  |
       h t        j                  du r| j
                  D ]  }|j                  |dd       d{   }|"|j!                  d      }t#        j$                   |t'        t)        t+        j,                               t/        j0                  t2        j4                        |xs |j6                  xs ||j8                  t:        j<                  |dd|	                    |j?                  | j
                  d       d{    |D ]w  }|j@                  }g }|D ]H  }|j                  tC        tE        |jF                  |j6                  |jH                        |             J t#        jJ                  |  d{    y |j?                  | j
                  d       d{   }|S 7 # t        $ r t	        ddd| i      w xY w7 7 7 T7 /w)a  
    delete team and associated team keys

    Parameters:
    - team_ids: List[str] - Required. List of team IDs to delete. Example: ["team-1234", "team-5678"]

    ```
    curl --location 'http://0.0.0.0:4000/team/delete'     --header 'Authorization: Bearer sk-1234'     --header 'Content-Type: application/json'     --data-raw '{
        "team_ids": ["8d916b1c-510d-4894-a334-1c16a93344f5"]
    }'
    ```
    r   )r   r   rX   Nr   r   r   r   r   r  rM   r  r  r  Tr   r   r   r   deletedz{}r   r   key)team_id_listr   )rM   rZ   r8  r  ra   )&r   r   r   rX   r   rY   rb   r   r   r   r   rf   re   rR   r   r   r   r   r   r   r   r   r   r   r   r   r   rZ   r   r   r   delete_datar   rz  r-   rM   r8  gather)rl   r   rN   r   r   r   rX   	team_rowsrM   team_row_baseteam_row_pydanticr   	_team_rowr  tasksteam_memberdeleted_teamss                    rU   delete_teamr    s    8  W>O4PQQ}}W>T4UVV *,I==	#&&88DD$g. E   
 $ % .K0H0H0JK*+ !& 4'}}G:G:P:PF} ;Q ; 5H  48I+!2tzz|,#+<<#=#5 $4,44$43+<+D+D#4#D#D")('+%." %> 
#
#5
#
QQQ 22'KLL"0 ( 0 0 + 3 3#.#9#9
 '8	 ( nne$$$! & (33]]v 4  M U  	#B7)!LM 	5< R& 	%su   AJ+I#6I 7I#A%J(J)CJ8J9A9J2J3&JJ	J I##I??JJJ	Jc                    | j                   t        j                  j                  k(  s'| j                   t        j                  j                  k(  ry | j
                  |j
                  k(  ry | j                  |j                  D cg c]  }|j                   c}vr3t        dddj                  | j                  |j
                        i      y c c}w )Nr   r   z-User={} not authorized to access this team={}r   )
r   r    r   r   PROXY_ADMIN_VIEW_ONLYrM   rZ   r   r   r$  )rN   r   r   s      rU   validate_membershipr  M  s     	##'7'C'C'I'II&&*:*P*P*V*VV 	!!Z%7%77  %88)		)  HOO%--z/A/A
 	
 )s   Cr|  c                 V   t         j                  j                  | j                  v r|t	               }| j                  D ]1  }|t         j                  j                  k7  s!|j                  |       3 |j                         D ]  }|j                  |        t        |      | _        | S r7  )r&   r  r   r   rp  addget_model_namesrC  )r|  r  team_modelsr  s       rU   _unfurl_all_proxy_modelsr  h  s     	**00I4D4DD" #%%E)::@@@& &  //1EOOE" 2,	rW   r{   team_info_response_objectc                    K   	 |j                   j                  j                  d| i       d {   }||_        |S 7 # t        $ r t        j                  d|         Y |S w xY ww)Nrw   r  zATeam member budget table not found, passed team_member_budget_id=)rb   litellm_budgettabler   r   r   r   r   )r{   rX   r  team_budgets       rU   _add_team_member_budget_tabler  y  s     

),,@@LL 56 M 
 
 >I!: %$
  
!!OPeOfg	
 %$
s1   A'+? =? A'? !A$ A'#A$$A'z
/team/infoz!Team ID in the request parameters)r   r   c                 t  K   ddl m} ddlm} 	 |t	        t
        j                  ddi      |t	        t
        j                  dd	i      	 |j                  j                  j                  d
|iddi       d{   }|t        	 t        |t        d#i |j                                |j!                  |ddt#        j$                                d{   }|g }|d}|D ]  }|t'        |dd      z  } d|i}|D ]%  }		 |	j                         }	|	j+                  dd       ' t-        ||gd       d{   }
t/        |t(              r	 |d#i |}n.t/        |t0              r |d#i |j                         }n |       }|j2                  |j2                  j5                  d      nd}|t7        |||       d{   }t9        ||||
      }|S 7 ^# t        $ r" t	        t
        j                  dd| di      w xY w7 3# t        $ r |	j)                         }	Y w xY w7 7 k# t        $ r}t;        j<                  dj?                  |tA        jB                                      t/        |t              rYtE        t'        |ddtG        |       d      tH        jJ                  t'        |dd      t'        |d t
        jL                        !      t/        |tD              r|tE        d"tG        |      z   tH        jJ                  t'        |dd      t
        jL                  !      d}~ww xY ww)$a#  
    get info on team + related keys

    Parameters:
    - team_id: str - Required. The unique identifier of the team to get info on.

    ```
    curl --location 'http://localhost:4000/team/info?team_id=your_team_id_here'     --header 'Authorization: Bearer your_api_key_here'
    ```
    r   )r*   r,  Nr   zDatabase not connected. Connect a database to your proxy - https://docs.litellm.ai/docs/simple_proxy#managing-auth---virtual-keysr   r>  z(Malformed request. No team id passed in.rM   r  Tr^   z Team not found, passed team id: r	  )rN   r   r  find_all)rM   r   r   expiresspendtokenrZ   r{   )r{   rX   r  )rM   r|  keysrh   z\litellm.proxy.management_endpoints.team_endpoints.py::team_info - Exception occurred - {}
{}r   zAuthentication Error()r@  Noner   r=  zAuthentication Error, ra   )'r|   r*   r   rX   r   r   HTTP_500_INTERNAL_SERVER_ERRORHTTP_422_UNPROCESSABLE_ENTITYrb   r   r   r   HTTP_404_NOT_FOUNDr  r   rf   r   r   r   r   r   r   rk   r   r   rz   r   r  r)   r   r   r$  	traceback
format_excr$   r   r#   
auth_errorHTTP_400_BAD_REQUEST)r   rM   rN   r*   rX   r|  r  r  kr  ri   
_team_infor{   response_objectr   s                  rU   r|  r|    s    , E8t
 "AA  a  ?"@@!#MN 
	#&&88DD$g.0$7 E      ! 	/(B9+?+?+AB	
 #++!LLN	 , 
 
 <DEGQ//  %(I C!nn& GGGT"  5G9d
 
 i&8E9EJ	9-8R9;O;O;QRJ8:J
 "". ##$;< 	
 !,<&;+*4  J 1 (	
 ]  	"55!%EgYa#PQ 	
*  !hhj!
$"  
""krr9'')	

 a' 8/DSVHA-NO$//a&1Qv/J/JK	  >*G,s1v5 ++!Wf-,,	
 	

s   L8>H3 .G =G>G 
AH3 H,H3 H&H3 =H/>BH3 H1H3 L8G +H		H3 H,(H3 +H,,H3 1H3 3	L5<C4L00L55L8z/team/blockc                    K   ddl m} |t        d      |j                  j                  j                  d| j                  iddi       d{   }|t        d	d
d| j                   i      |S 7 $w)a  
    Blocks all calls from keys with this team id.

    Parameters:
    - team_id: str - Required. The unique identifier of the team to block.

    Example:
    ```
    curl --location 'http://0.0.0.0:4000/team/block'     --header 'Authorization: Bearer sk-1234'     --header 'Content-Type: application/json'     --data '{
        "team_id": "team-1234"
    }'
    ```

    Returns:
    - The updated team record with blocked=True



    r   r,  NNo DB Connected.rM   blockedTr   r  r   r  r   r   rX   r   rb   r   r   rM   r   rl   r   rN   rX   records        rU   
block_teamr    s     > 9*++ ##55<<$,,'y$.? =  F ~>t||nMN
 	

 M   AA5A3%A5z/team/unblockc                    K   ddl m} |t        d      |j                  j                  j                  d| j                  iddi       d{   }|t        d	d
d| j                   i      |S 7 $w)ay  
    Blocks all calls from keys with this team id.

    Parameters:
    - team_id: str - Required. The unique identifier of the team to unblock.

    Example:
    ```
    curl --location 'http://0.0.0.0:4000/team/unblock'     --header 'Authorization: Bearer sk-1234'     --header 'Content-Type: application/json'     --data '{
        "team_id": "team-1234"
    }'
    ```
    r   r,  Nr  rM   r  Fr   r  r   r  r   r  r  s        rU   unblock_teamr  L  s     2 9*++ ##55<<$,,'y%.@ =  F ~>t||nMN
 	

 Mr  z/team/availablec           	        K   ddl m} |'t        ddt        j                  j
                  i      t        t        t        t              t        j                  t        j                  j                  d      nd       }|t        dddi      |j                  j                  j                  d|j                   i	       d {   }|t        d
ddi      t#        di |j%                         }|D cg c]  }||j&                  vs| }}|j                  j(                  j+                  dd|ii	       d {   }|D cg c]  }t-        di |j%                          }	}|	S 7 c c}w 7 3c c}w w)Nr   r,  r   r   r   rQ   zNo available teams for user to join. See how to set available teams here: https://docs.litellm.ai/docs/proxy/self_serve#all-settings-for-self-serve--sso-flowrZ   r  r  zUser not foundrM   r\   ra   )r   rX   r   r   r  r   r   r   r   r   rR   rS   r   rb   rq  r   rZ   r   rf   ro  r   rd   r   )
r   rN   r   rX   rQ   	user_infouser_info_correct_typer   available_teams_dbavailable_teams_correct_types
             rU   list_available_teamsr  w  s     9.EEKKL
 	

 c 33? 00445FGO   y
 	
 $&&88DD+334 E  I -.
 	
 /H1E1E1GH )D8N8T8T,TO   -//AAKK412  L   
 <N$37.DOO-.$  $ ('-$sH   CE:E,2E:8E.E./E:?E3 E: E5(E:.E:5E:z/v2/team/list)r   r   r   z1Only return teams which this 'user_id' belongs toz9Only return teams which this 'organization_id' belongs toz1Only return teams which this 'team_id' belongs tozPOnly return teams which this 'team_alias' belongs to. Supports partial matching.rB  zPage number for pagination)r   r   ge
   zNumber of teams per paged   )r   r   r  lez>Column to sort by (e.g. 'team_id', 'team_alias', 'created_at')asczSort order ('asc' or 'desc')r
  r~   page	page_sizesort_by
sort_orderc
                   K   ddl m}
 |
t        ddd|
 i      |)|	j                  t        j
                  k7  r|	j                  }|dz
  |z  }i }|r||d	<   |r|d
d|d<   |r||d<   |r	 |
j                  j                  j                  d|i       d{   }|t        ddd| i      t        di |j                         }|d|j                  i|d	<   n&||j                  v r||d	<   nt        ddd| i      g d}d}|r*||v r&|j                         dvrd}||j                         i}|
j                  j                  j!                  ||||r|nddi       d{   }|
j                  j                  j#                  |       d{   }| |z   }|r|D cg c]  }|j                          c}ng ||||dS 7 2# t        $ r t        ddd| i      w xY w7 7 Wc c}w w)a  
    Get a paginated list of teams with filtering and sorting options.

    Parameters:
        user_id: Optional[str]
            Only return teams which this user belongs to
        organization_id: Optional[str]
            Only return teams which belong to this organization
        team_id: Optional[str]
            Filter teams by exact team_id match
        team_alias: Optional[str]
            Filter teams by partial team_alias match
        page: int
            The page number to return
        page_size: int
            The number of items per page
        sort_by: Optional[str]
            Column to sort by (e.g. 'team_id', 'team_alias', 'created_at')
        sort_order: str
            Sort order ('asc' or 'desc')
    r   r,  Nr   r   zNo db connected. prisma client=r   rB  rM   insensitivecontainsmoder~   r
  rZ   r  r  zUser not found, passed user_id=r\   z User is not a member of team_id=)rM   r~   r  )r  r  r  r  r  r_   skiptaker  )ro  totalr  r  total_pagesra   )r   rX   r   r   r    r   rZ   rb   rq  r   r   r   rf   ro  lowerr   rd   r   )r   rZ   r
  rM   r~   r  r  r  r  rN   rX   r  where_conditionsuser_objectuser_object_correct_typevalid_sort_columnsorder_byro  total_countr  r   s                        rU   list_team_v2r    s    t 9>}oNO
 	

 ,66:J:V:VV#++ 1H	!D (*&-#"!*
&
 .=*+	 - 0 0 B B N N '* !O ! K #B7)!LM  $5#P{7M7M7O#P ?+/1I1O1O*PY'0666*1Y'#CG9!MN  AH700_4JZ--/0  ""44>>"hv(>	 ?  E &((::@@GW@XXK !LI-.K ;@6$//#6R" ]  	#B7)!LM 	> Y 7sa   A*G5-+G G
G CG5(G,)-G5G.G5(G0?G5
G G))G5.G50G5z
/team/listc           
      J  K   ddl m} t        ||      s(t        dddj	                  |j
                        i      |'t        d	dt        j                  j                  i      |j                  j                  j                  d
di       d{   }g }|rK|D ]E  }|j                  s|j                  D ]'  }d|v s|d   |d   |k(  s|j                  |       ) G n|}|D cg c]  }|j                   }	}t        ||	|       d{   }
g }|D ]  }g }|
D ]-  }|j                  |j                  k(  s|j                  |       / |j                  j                   j                  d|j                  i       d{   }	 |j                  t#        di |j%                         ||d        |j/                  d        |Y|t0        j2                  j                  k(  r|D cg c]  }|j4                  | }}|S |D cg c]  }|j4                  |k(  r| }}|S 7 c c}w 7 "7 # t&        $ rT}dj	                  |j                  |j%                         t)        |            }t+        j,                  |       Y d}~vd}~ww xY wc c}w c c}w w)a  
    ```
    curl --location --request GET 'http://0.0.0.0:4000/team/list'         --header 'Authorization: Bearer sk-1234'
    ```

    Parameters:
    - user_id: str - Optional. If passed will only return teams that the user_id is a member of.
    - organization_id: str - Optional. If passed will only return teams that belong to the organization_id. Pass 'default_organization' to get all teams without organization_id.
    r   r,  )rN   requested_user_idi  r   zCOnly admin users can query all teams/other teams. Your user role={}r   Nr   r   T)r`   rZ   r  rM   r  )rh   r  zWInvalid team object for team_id: {}. team_object={}.
            Error: {}
            c                 $    t        | dd      xs dS )Nr~    )r   )xs    rU   <lambda>zlist_team.<locals>.<lambda>	  s    71lB+G+M2+MrW   )r  ra   )r   rX   r4   r   r$  r   r   r  r   rb   r   rd   r   re   rM   rk   litellm_verificationtokenr+   rf   r   r   r   r  sortr%   DEFAULT_ORGANIZATIONr
  )r   rZ   r
  rN   rX   r  filtered_responser   r   	_team_idsri   returned_responses_team_membershipsrj   r  r   team_exceptions                    rU   	list_teamr  ?	  s    , 9++w ^ee%//
 	
 .EEKKL
 	

 #%%77AA!4
 B  H D&&"55F!V+"9-9"9-8)006 6  %*;<$<I<0y' K 8:!:<BzzT\\)!((, 
 #%%??IIdll+ J 
 
	%%& oo'%6 "8  NO"<QQWWW!3"t7K7K7S" " 	 /"''?: " " K* =
  	doo/Q 
 !**>:	""s   BJ#H,J#-J#J#J#J#,H/?J#H4+J#?AJ#H7J#-H9:8J#2JJJ#J(J#/J#7J#9	JA	JJ#JJ#c                 L  K   	 |dz
  |z  }| j                   j                  j                          d{   }| j                   j                  j                  ||ddi       d{   }||fS 7 :7 
# t        $ r&}t        j                  d|        g dfcY d}~S d}~ww xY ww)a5  
    Get paginated list of teams from team table

    Parameters:
        prisma_client: PrismaClient - The database client
        page_size: int - Number of teams per page
        page: int - Page number (1-based)

    Returns:
        Tuple[List[LiteLLM_TeamTable], int] - (list of teams, total count)
    rB  Nr~   r  )r  r  r  z.[Non-Blocking] Error getting paginated teams: r   )rb   r   r   rd   r   r   r  )rX   r  r  r  r  ro  r   s          rU   get_paginated_teamsr  	  s      qI%),,>>DDFF $&&88BBIlE-B C 
 
 k!! G
  &&<QC@	
 1u	sV   B$/A2 A.1A2 %A0&A2 -B$.A2 0A2 2	B!;BB!B$B!!B$r   c                     |t         v r
t                || v r1| |   +| j                  |      }d| v r| d   	|| d   |<   y||i| d<   yyy)z
    Helper function to update metadata fields that require premium user checks in the update endpoint

    Args:
        updated_kv: The key-value dict being used for the update
        field_name: Name of the metadata field being updated
    Nrz   )r   rC   r   )r   r   _values      rU   r#  r#  	  sl     FFZJz$:$F
+#
:(>(J17Jz":.&0&%9Jz" %GrW   z/team/filter/uiF   r  )r   r   include_in_schema	responsesz$Team alias in the request parameters2   zNumber of items per pagec                 @  K   ddl m} |t        dddi      	 |dz
  |z  }i }| r| d	d
|d<   |r|d	d
|d<   |j                  j                  j                  |||ddi       d{   }|sg S |S 7 
# t        $ r}	t        ddt        |	             d}	~	ww xY ww)a  
    [PROXY-ADMIN ONLY] Filter teams based on partial match of team_id or team_alias with pagination.

    Args:
        user_id (Optional[str]): Partial user ID to search for
        user_email (Optional[str]): Partial email to search for
        page (int): Page number for pagination (starts at 1)
        page_size (int): Number of items per page (max 100)
        user_api_key_dict (UserAPIKeyAuth): User authentication information

    Returns:
        List[LiteLLM_SpendLogs]: Paginated list of matching user records
    r   r,  Nr   r   r   r   rB  r  r  rM   r~   r  r  r  zError searching teams: )r   rX   r   rb   r   rd   r   r   )
rM   r~   r  r  rN   rX   r  r  ro  r   s
             rU   ui_view_teamsr	  	  s     J 9W>O4PQQ!XqI% #%+Y'
 &%.\* $&&88BB"(	 C 
 
 I
  X6McRSfX4VWWXsG   BAA4 'A2(A4 /B0A4 1B2A4 4	B=BBBrH  
new_modelsc                     | j                   }|*t        |      dk(  rt        j                  j                  g}n| j                   }t        t        ||z               }|S )z8
    Add new models to a team's allowed model list.
    r   )r   r   r&   r  r   rC  rp  )rH  r
  current_modelsupdated_modelss       rU   add_new_models_to_teamr  5
  sV     __N"s>':a'?+<<BBC!#nz9:;NrW   z/team/model/addc                 T  K   ddl m} |t        dddi      |j                  j                  j                  d| j                  i	       d{   }|t        d
dd| j                   i      t        di |j                         }|j                  t        j                  j                  k7  rt        ||      st        dddi      t        || j                        }|j                  j                  j!                  d| j                  id|i       d{   }|S 7 7 w)a
  
    Add models to a team's allowed model list. Only proxy admin or team admin can add models.

    Parameters:
    - team_id: str - Required. The team to add models to
    - models: List[str] - Required. List of models to add to the team

    Example Request:
    ```
    curl --location 'http://0.0.0.0:4000/team/model/add'     --header 'Authorization: Bearer sk-1234'     --header 'Content-Type: application/json'     --data '{
        "team_id": "team-1234",
        "models": ["gpt-4", "claude-2"]
    }'
    ```
    r   r,  Nr   r   r   r   rM   r  r  r  rG  r   5Only proxy admin or team admin can modify team models)rH  r
  r   r   ra   )r   rX   r   rb   r   r   rM   r   rf   r   r    r   r   r9   r  r   r   )rl   r   rN   rX   r   rH  r  r_  s           rU   team_model_addr  F
  sA    : 9W>O4PQQ #%%77CC$,,' D  H >t||nMN
 	

 !98#6#6#89H 	##'7'C'C'I'II#/(
 TU
 	

 ,X$++VN&));;BB$,,'x.H C  L =4s%   AD(D$CD(D&D(&D(z/team/model/deletec                   K   ddl m} |t        dddi      |j                  j                  j                  d| j                  i	       d{   }|t        d
dd| j                   i      t        di |j                         }|j                  t        j                  j                  k7  rt        ||      st        dddi      |j                  xs g }|D cg c]  }|| j                  vs| }}|j                  j                  j                  d| j                  id|i       d{   }	|	S 7 c c}w 7 w)a  
    Remove models from a team's allowed model list. Only proxy admin or team admin can remove models.

    Parameters:
    - team_id: str - Required. The team to remove models from
    - models: List[str] - Required. List of models to remove from the team

    Example Request:
    ```
    curl --location 'http://0.0.0.0:4000/team/model/delete'     --header 'Authorization: Bearer sk-1234'     --header 'Content-Type: application/json'     --data '{
        "team_id": "team-1234",
        "models": ["gpt-4"]
    }'
    ```
    r   r,  Nr   r   r   r   rM   r  r  r  rG  r   r  r   r   ra   )r   rX   r   rb   r   r   rM   r   rf   r   r    r   r   r9   r   r   )
rl   r   rN   rX   r   rH  r  r   r  r_  s
             rU   team_model_deleter  
  sg    : 9W>O4PQQ #%%77CC$,,' D  H >t||nMN
 	

 !98#6#6#89H 	##'7'C'C'I'II#/(
 TU
 	
 __*N "0HA1DKK3GaHNH '));;BB$,,'x.H C  L G8 Is7   AED;BE"D=6D=::E4E5E=Ez/team/permissions_listc           	      r  K   ddl m}m}m} |t	        dddi      t        | ||d|dd	
       d{   }|t	        ddd|  i      t        di |j                         }t        |d      rt|j                  t        j                  j                  k7  rMt        ||      s@t        |j                  |      s)t	        dddj!                  d|j                        i      |j"                  t%        j&                         |_        t)        | |j"                  t%        j*                               S 7 w)z4
    Get the team member permissions for a team
    r   rX   r  r  Nr   r   r   r   FTra  r  re  r   rG  rT   r   rI  rJ  )rM   team_member_permissionsall_available_permissionsra   )r   rX   r  r  r   r6   r   rf   rK  r   r    r   r   r9   rV   rM   r$  r  r?   default_team_member_permissionsrI   )get_all_available_team_member_permissions)rM   rN   rX   r  r  r  r   s          rU   r  r  
  sc      W>O4PQQ .#-+   :7)DE
 	

 +L->-I-I-KL 	!;/''+;+G+G+M+MM#/:L
 #&../

 ell&&..
 	
 008&FFH 	1 , 1 I I"<"f"f"h Ws   1D7D4DD7z/team/permissions_updatec           	        K   ddl m}m}m} |t	        dddi      t        | j                  ||d|dd	
       d{   }|t	        ddd| j                   i      t        di |j                         }t        |d      rt|j                  t        j                  j                  k7  rMt        ||      s@t        |j                  |      s)t	        dddj!                  d|j                        i      |j"                  j$                  j'                  d| j                  id| j(                  i       d{   }|S 7 7 	w)z7
    Update the team member permissions for a team
    r   r  Nr   r   r   r   FTra  r  re  r   rG  rT   r   rI  rJ  rM   r  r   ra   )r   rX   r  r  r   r6   rM   r   rf   rK  r   r    r   r   r9   rV   r$  rb   r   r   r  )	rl   r   rN   rX   r  r  r  r   r_  s	            rU   update_team_member_permissionsr    st      W>O4PQQ .#-+   :4<<.IJ
 	

 +L->-I-I-KL 	!;/''+;+G+G+M+MM#/:L
 #&../

 ell&&..
 	
 '));;BB$,,'')E)EF C  L
 WLs"   ;EEC=E;E<EEz/team/daily/activity)r   r   
start_dateend_dater   exclude_team_idsc	                 :  K   ddl m}	m}
m} |	't	        ddt
        j                  j                  i      | r| j                  d      nd}d}|r|r|j                  d      nd}t        |      st        |j                  |	d||j                  |
d	
       d{   }|(t	        dddj                  |j                        i      ||j                  }n3|D ].  }||j                  vst	        dddj                  |      i       i }|rdt        |      i|d<   |	j                   j"                  j%                  |       d{   }|D ci c]  }|j&                  d|j(                  i }}t+        |	dd|||||||||       d{   S 7 7 Kc c}w 7 w)a  
    Get daily activity for specific teams or all teams.

    Args:
        team_ids (Optional[str]): Comma-separated list of team IDs to filter by. If not provided, returns data for all teams.
        start_date (Optional[str]): Start date for the activity period (YYYY-MM-DD).
        end_date (Optional[str]): End date for the activity period (YYYY-MM-DD).
        model (Optional[str]): Filter by model name.
        api_key (Optional[str]): Filter by API key.
        page (int): Page number for pagination.
        page_size (int): Number of items per page.
        exclude_team_ids (Optional[str]): Comma-separated list of team IDs to exclude.
    Returns:
        SpendAnalyticsPaginatedResponse: Paginated response containing daily activity data.
    r   r  Nr   r   r   ,FT)rZ   rX   user_id_upsertr  rb  r  rd  r  zUser= {} not foundzGUser does not belong to Team= {}. Call `/user/info` to see user's teamsr\   rM   r  r~   litellm_dailyteamspend)rX   r   entity_id_field	entity_identity_metadata_fieldexclude_entity_idsr  r  r  r   r  r  )r   rX   r  r  r   r   r  r   splitr<   r7   rZ   rb  r$  ro  rC  rb   r   rd   rM   r~   r=   )rY   r  r  r  r   r  r  r  rN   rX   r  r  team_ids_listexclude_team_ids_listr  rM   where_conditionteam_aliasestteam_alias_metadatas                       rU   get_team_daily_activityr.  c  s    >  .EEKKL
 	
 ,4HNN3'M15+;""3' 	   12)%--' 1.??/
 
	 1889J9R9RS   %OOM ))//1'$'#%n%u%u '&   ) O&*D,?%@	"&));;EE F  L :F45		L!,,//  $#+!10  W
HsJ   BFFAF*AFFF F/FFFFFr7  )r  rB  )__doc__r   r   r  r   r   r   typingr   r   r   r   r	   r
   r   fastapir   r   r   r   r   r   pydanticr   rR   litellm._loggingr   r|   r   r   r   r   r   r   r   r   r   r   r   r   r    r!   r"   r#   r$   r%   r&   r'   r(   r)   r*   r+   r,   r-   r.   r/   r0   r1   r2   r3   r  r4   r5   r6   r7   $litellm.proxy.auth.user_api_key_authr8   /litellm.proxy.management_endpoints.common_utilsr9   r:   r;   r<   ;litellm.proxy.management_endpoints.tag_management_endpointsr=   8litellm.proxy.management_helpers.object_permission_utilsr>   >litellm.proxy.management_helpers.team_member_permission_checksr?   &litellm.proxy.management_helpers.utilsr@   rA   litellm.proxy.utilsrB   rC   rD   litellm.routerrE   >litellm.types.proxy.management_endpoints.common_daily_activityrF   7litellm.types.proxy.management_endpoints.team_endpointsrG   rH   rI   rJ   rK   rL   routerr   boolrV   rk   r   floatr   r   postr   r   r   r  r*  r"  r2  r4  rE  rM  rV  r\  r   rf  rj  rz  r  r  r  r  r  r  r  r   Queryr|  r  r  r  intr  r  r  r#  r	  r  r  r  r  r  r.  ra   rW   rU   <module>rD     s<  	     ' @ @ @  N N   1! ! ! ! ! ! ! ! !D  C  
 "  
  4  PT+/9?G}	
 !2&
 11
2&& && 	&
 
&R,!,%, , 	,
 
,` 
	+,-$	    )00A(B(. t)	T+
T+T+ &T+ !	T+ T+n!
!sm!  ! &	!
 "! c]!H
L) c]0[
[+D[RX[	[| +,GDU<V;W    )00A(B(. t)	P;
P;P; &P; !	P; P;f(9	8&$v,&'$GL)G
G G21

1
(1
h
%
)
 

6A3
A3)A3  A3 &	A3
 "A3 4!"D)?$@@AA3H6A
6A)6A )*6A 
	6ArA
A)A  A &	A
 "A d#45t<R7SSTAD 
	+,-(	    )00A(BW
W%W Wt/(/
!/ 4f/4 
	+,-  
  )00A(Bo
!o%o od 
	+,-+	    )00A(BA
!AA &A AH$&\$#$ 

$N 
	+,-,	    )00A(B|

"|
%|
 |
~ +,GDU<V;W    )00A(B(. t)	s
ss &s !	s sl
%
3D
6 .4"%%%  ?% %	%$ )*'BS:T9U    !7=="E )00A(BI
I
I

 &I
 I
X *+7CT;U:V    )00A(B*
** &* *Z ,-WEV=W<X    )00A(B$
$$ &$ $N  )00A(B)*4(4(%4( 4(n 
	#+,-	   +W]]"U &3W]]O& +W]]"U !.f! ; #W]] :qS +W]]T $gmm#A )00A(B;GGc]G
 c]G c]G G  !G& 'G, c]-G4 5G: &;GGT )*'BS:T9U    +W]]"U &*(/0A(Bkkc]k
 c]k &k k`   4!"C'(	D:D :c :d :( 
	+,-gt-./   +W]]"E !."H! ; #W]] :qS )00A(BBXc]BX 	BX BX BX &BXBXJ-1#Y	#Y" 
	+,-  
  )00A(B;
;; &; ;| 
	+,-  
  )00A(B@
 @@ &@ @F 
	+,-  
  7=="E )00A(B	BB &	B
 &B BJ 
	+,-   )00A(B=
,== &= 	=
=@ 2
	   # $"!&*(/0A(Bhsmhh smh C=	h
 c]h h h smh &h
hrW   