
    g@                        d Z ddlZddlmZmZmZ ddlmZmZm	Z	m
Z
mZ ddl ddlmZ ddlmZmZ ddlmZ  e       Zej+                  d	d
g ee      ge       ee      fdedefd       Zej+                  dd
g ee      g      d        Zej+                  dd
g ee      g      d        Zej9                  dd
g ee      g       ee      fdefd       Zej+                  dd
g ee      g      defd       Zej+                  dd
g ee      ge       e ee      fde!de
dede fd              Z"de#de$dedee%e&f   fdZ'y) z
Endpoints for /organization operations

/organization/new
/organization/update
/organization/delete
/organization/member_add
/organization/info
/organization/list
    N)ListOptionalTuple)	APIRouterDependsHTTPExceptionRequeststatus)*)user_api_key_auth)get_new_internal_user_defaultsmanagement_endpoint_wrapper)PrismaClientz/organization/newzorganization management)tagsdependenciesresponse_modeldatauser_api_key_dictc           	        K   ddl m}m} |t        dddi      |j                  |j                  t
        j                  k7  rt        ddd	|j                   i      | j                  	 t        j                  j                         }| j                  d
      }|j                         D ci c]  \  }}||v s|| }}}t        di |}	|j                  |	j                  d
            }
|j                  j                  j!                  i |
|j"                  xs ||j"                  xs |d       d{   }|j                  | _        	 t%        |j&                        dk(  rnet%        | j&                        dk(  rt        dddi      | j&                  D ]/  }||j&                  vst        ddd| d|j&                   i       t)        di | j                  d
      |j"                  xs ||j"                  xs |d}|j                  |j                  d
            }|j                  j*                  j!                  i |       d{   }|S c c}}w 7 *7 w)a	  
    Allow orgs to own teams

    Set org level budgets + model access.

    Only admins can create orgs.

    # Parameters

    - organization_alias: *str* - The name of the organization.
    - models: *List* - The models the organization has access to.
    - budget_id: *Optional[str]* - The id for a budget (tpm/rpm/max budget) for the organization.
    ### IF NO BUDGET ID - CREATE ONE WITH THESE PARAMS ###
    - max_budget: *Optional[float]* - Max budget for org
    - tpm_limit: *Optional[int]* - Max tpm limit for org
    - rpm_limit: *Optional[int]* - Max rpm limit for org
    - max_parallel_requests: *Optional[int]* - [Not Implemented Yet] Max parallel requests for org
    - soft_budget: *Optional[float]* - [Not Implemented Yet] Get a slack alert when this soft budget is reached. Don't block requests.
    - model_max_budget: *Optional[dict]* - Max budget for a specific model
    - budget_duration: *Optional[str]* - Frequency of reseting org budget
    - metadata: *Optional[dict]* - Metadata for team, store information for team. Example metadata - {"extra_info": "some info"}
    - blocked: *bool* - Flag indicating if the org is blocked or not - will stop all calls from keys with this org_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)


    Case 1: Create new org **without** a budget_id

    ```bash
    curl --location 'http://0.0.0.0:4000/organization/new' 
    --header 'Authorization: Bearer sk-1234' 
    --header 'Content-Type: application/json' 
    --data '{
        "organization_alias": "my-secret-org",
        "models": ["model1", "model2"],
        "max_budget": 100
    }'


    ```

    Case 2: Create new org **with** a budget_id

    ```bash
    curl --location 'http://0.0.0.0:4000/organization/new' 
    --header 'Authorization: Bearer sk-1234' 
    --header 'Content-Type: application/json' 
    --data '{
        "organization_alias": "my-secret-org",
        "models": ["model1", "model2"],
        "budget_id": "428eeaa8-f3ac-4e85-a8fb-7dc8d7aa8689"
    }'
    ```
    r   )litellm_proxy_admin_nameprisma_clientN  errorNo db connectedstatus_codedetail  z,Only admins can create orgs. Your role is = T)exclude_none)
created_by
updated_byr     z\User not allowed to give access to all models. Select models you want org to have access to.z)User not allowed to give access to model=z. Models you have access to =  )litellm.proxy.proxy_serverr   r   r   	user_roleLitellmUserRolesPROXY_ADMIN	budget_idLiteLLM_BudgetTablemodel_fieldskeysjsonitemsjsonify_objectdblitellm_budgettablecreateuser_idlenmodelsLiteLLM_OrganizationTablelitellm_organizationtable)r   r   r   r   budget_params
_json_datakv_budget_data
budget_row
new_budget_budgetmorganization_rownew_organization_rowresponses                   n/var/www/openai/venv/lib/python3.12/site-packages/litellm/proxy/management_endpoints/organization_endpoints.pynew_organizationrE      s    N SW>O4PQQ 	##+&&*:*F*FFGHYHcHcGde
 	
 ~~	
 ,88==? YYDY1
)3)9)9);R);AqM?Q1);R(8<8
"11*//t/2TU
%((<<CC/77S;S/77S;S D 
 
 !** ##$)t{{q {  A)000# ##LQCOmn  oG  oG  nH  "I   1 
)))
&$,,H0H$,,H0H
 )7740 #%%??FF
"
 G  H Oe S

Ns?   B/I-1I">I"A;I->I(?A3I-3B(I-I+I-+I-z/organization/update)r   r   c                      K   t        d      wzd[TODO] Not Implemented yet. Let us know if you need this - https://github.com/BerriAI/litellm/issueszNot Implemented YetNotImplementedErrorr$       rD   update_organizationrK            3
44   z/organization/deletec                      K   t        d      wrG   rH   r$   rJ   rD   delete_organizationrO      rL   rM   z/organization/listc                 |  K   ddl m} |t        dddi      | j                  | j                  t        j
                  k7  rt        ddd	| j                   i      |'t        d
dt        j                  j                  i      |j                  j                  j                  ddi       d{   }|S 7 w)z
    ```
    curl --location --request GET 'http://0.0.0.0:4000/organization/list'         --header 'Authorization: Bearer sk-1234'
    ```
    r   r   Nr   r   r   r   r   z*Only admins can list orgs. Your role is = r#   membersT)include)r%   r   r   r&   r'   r(   CommonProxyErrorsdb_not_connected_errorvaluer0   r7   	find_many)r   r   rC   s      rD   list_organizationrX      s      9W>O4PQQ 	##+&&*:*F*FFEFWFaFaEbc
 	
 .EEKKL
 	
 #%%??IID! J  H O	s   B1B<3B:4B<z/organization/infoc                 &  K   ddl m} |t        dddi      t        | j                        dk(  rt        ddd	| j                   i      |j
                  j                  j                  d
d| j                  iiddi       d{   }|S 7 w)z*
    Get the org specific information
    r   rQ   Nr   r   r   r   r#   z6Specify list of organization id's to query. Passed in=organization_idinlitellm_budget_tableT)whererS   )r%   r   r   r4   organizationsr0   r7   rW   )r   r   rC   s      rD   info_organizationr_      s      9W>O4PQQ
4!#QRVRdRdQef
 	
 #%%??II 4););"<='. J  H
 Os   BBB	Bz/organization/member_addhttp_requestreturnc                   K   	 ddl m} |t        dddi      |j                  j                  j                  d| j                  i	       d{   }|t        d
ddt        | dd       i      t        | j                  t              r| j                  }n| j                  g}g }g }|D ]G  }t        || j                  |       d{   \  }	}
|j                  |	       |j                  |
       I t        | j                  ||      S 7 7 E# t        $ r}t        |t              rYt        t        |ddt!        |       d      t"        j$                  t        |dd      t        |dt&        j(                              t        |t              r|t        dt!        |      z   t"        j$                  t        |dd      t&        j(                        d}~ww xY ww)a  
    [BETA]

    Add new members (either via user_email or user_id) to an organization

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

    Only proxy_admin or org_admin of organization, allowed to access this endpoint.

    # Parameters:

    - organization_id: str (required)
    - member: Union[List[Member], Member] (required)
        - role: Literal[LitellmUserRoles] (required)
        - user_id: Optional[str]
        - user_email: Optional[str]

    Note: Either user_id or user_email must be provided for each member.

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

    The following is executed in this function:

    1. Check if organization exists
    2. Creates a new Internal User if the user_id or user_email is not found in LiteLLM_UserTable
    3. Add Internal User to the `LiteLLM_OrganizationMembership` table
    r   rQ   Nr   r   r   r   rZ   r]     z+Organization not found for organization_id=)memberrZ   r   )rZ   updated_users updated_organization_membershipsr   zAuthentication Error()paramNoner   )messagetyperi   codezAuthentication Error, )r%   r   r   r0   r7   find_uniquerZ   getattr
isinstancere   r   add_member_to_organizationappendOrganizationAddMemberResponse	ExceptionProxyExceptionstrProxyErrorTypes
auth_errorr
   HTTP_500_INTERNAL_SERVER_ERROR)r   r`   r   r   existing_organization_rowrR   rf   rg   re   updated_userupdated_organization_membershipes               rD   organization_member_addr~     s    h=
< CBS8TUU  ""<<HH($*>*>? I   	"
 %,J7SWYjlpKqJrs  dkk4(kkG{{mG13VX(F0!$($8$8"/  :L9   .,334ST  - 00'-M
 	
C.  
a' 8/DSVHA-NO$//a&1Qv/T/TU	  >*G,s1v5 ++!Wf-66	
 	

sP   G"AD DA;D DAD G"D D 	GB=GGG"re   rZ   r   c                   K   	 d}d}d}| j                   :|j                  j                  j                  d| j                   i       d{   }| j                  :|j                  j                  j                  d| j                  i       d{   }|{|y| j                   xs t        t        j                               }t        || j                        }|j                  |d       d{   }|t        di |j                         }n|t        |      dkD  rt        d	d
di      |t        di |j                         }nE|t        di |j                         }n)t        dd
d| j                    d| j                   i      |%t        d| j                    d| j                         |j                  j                  j!                  ||j                   | j"                  d       d{   }	t%        di |	j                         }
||
fS 7 7 7 17 *# t&        $ r}t        d|       d}~ww xY ww)z
    Add a member to an organization

    - Checks if member.user_id or member.user_email is in LiteLLM_UserTable
    - If not found, create a new user in LiteLLM_UserTable
    - Add user to organization in LiteLLM_OrganizationMembership
    Nr3   rc   
user_email)r3   r   user)r   
table_name   r#   r   zIMultiple users with this email found in db. Please use 'user_id' instead.r   rd   zUser not found for user_id=z and user_email=z2User does not exist in LiteLLM_UserTable. user_id=)rZ   r3   r&   r"   z%Error adding member to organization: r$   )r3   r0   litellm_usertablern   r   rv   uuiduuid4r   insert_dataLiteLLM_UserTable
model_dumpr4   r   
ValueErrorlitellm_organizationmembershipr2   role#LiteLLM_OrganizationMembershipTablert   )re   rZ   r   user_objectexisting_user_id_rowexisting_user_email_rowr3   new_user_defaults_returned_user_organization_membershiporganization_membershipr}   s               rD   rq   rq     s    EF37#"&>>%)6)9)9)K)K)W)W &..1 *X * $  (#&&88DD'):):; E   $  ',C,K!>>>S->G >!,,!
 $1#<#<BS`f#<#ggN)/N.2K2K2MN$0S9P5QTU5Uh  %0+S.E.P.P.RSK!-+P.B.M.M.OPK:6>>:JJZ[a[l[lZmn  DV^^DTTdekevevdwx   ""AAHH'6*22!' I   	! #F #
&113#
 333y$ h:  F@DEEFst   IAH( HAH( H A H( 2H#3DH( ;H&< H( IH(  H( #H( &H( (	I1H??II)(__doc__r   typingr   r   r   fastapir   r   r   r	   r
   litellm.proxy._types$litellm.proxy.auth.user_api_key_authr   &litellm.proxy.management_helpers.utilsr   r   litellm.proxy.utilsr   routerpostNewOrganizationResponseNewOrganizationRequestUserAPIKeyAuthrE   rK   rO   getrX   OrganizationRequestr_   rs   OrganizationMemberAddRequestr~   	OrgMemberrv   r   r   rq   r$   rJ   rD   <module>r      s=  	  ( ( F F " B -	 
#	$+,-*	   )00A(BM
 M%MM` 
#	$+,-  
5
5
 
#	$+,-  
5
5
 
#	$+,-   )00A(B!%!
!H 
#	$+,-  
"5 
0 
#	$+,-0	    )00A(Bj

&j
j
 &j
 #	j
 j
ZRFRFRF  RF AAB	RFrJ   