Skip to content

Commit

Permalink
Add remaining org CRUD endpoints + support deleting orgs on UI (Berri…
Browse files Browse the repository at this point in the history
…AI#8561)

* feat(organization_endpoints.py): expose new `/organization/delete` endpoint. Cascade org deletion to member, teams and keys

Ensures any org deletion is handled correctly

* test(test_organizations.py): add simple test to ensure org deletion works

* feat(organization_endpoints.py): expose /organization/update endpoint, and define response models for org delete + update

* fix(organizations.tsx): support org delete on UI + move org/delete endpoint to use DELETE

* feat(organization_endpoints.py): support `/organization/member_update` endpoint

Allow admin to update member's role within org

* feat(organization_endpoints.py): support deleting member from org

* test(test_organizations.py): add e2e test to ensure org member flow works

* fix(organization_endpoints.py): fix code qa check

* fix(schema.prisma): don't introduce ondelete:cascade - breaking change

* docs(organization_endpoints.py): document missing params

* refactor(organization_view.tsx): initial commit creating a generic update member component shared between org and team member classes

* feat(organization_view.tsx): support updating org member role on UI

* feat(organization_view.tsx): allow proxy admin to delete members from org
  • Loading branch information
krrishdholakia authored and abhijitherekar committed Feb 20, 2025
1 parent 5b5b8e5 commit b4057bc
Show file tree
Hide file tree
Showing 9 changed files with 929 additions and 91 deletions.
1 change: 0 additions & 1 deletion litellm/proxy/_experimental/out/onboarding.html

This file was deleted.

46 changes: 44 additions & 2 deletions litellm/proxy/_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,14 @@
from typing import TYPE_CHECKING, Any, Dict, List, Literal, Optional, Union

import httpx
from pydantic import BaseModel, ConfigDict, Field, Json, model_validator
from pydantic import (
BaseModel,
ConfigDict,
Field,
Json,
field_validator,
model_validator,
)
from typing_extensions import Required, TypedDict

from litellm.types.integrations.slack_alerting import AlertType
Expand Down Expand Up @@ -393,6 +400,7 @@ class LiteLLMRoutes(enum.Enum):
"/organization/info",
"/organization/delete",
"/organization/member_add",
"/organization/member_update",
]

# All routes accesible by an Org Admin
Expand Down Expand Up @@ -1110,6 +1118,10 @@ class OrganizationRequest(LiteLLMPydanticObjectBase):
organizations: List[str]


class DeleteOrganizationRequest(LiteLLMPydanticObjectBase):
organization_ids: List[str] # required


class KeyManagementSystem(enum.Enum):
GOOGLE_KMS = "google_kms"
AZURE_KEY_VAULT = "azure_key_vault"
Expand Down Expand Up @@ -1494,6 +1506,18 @@ class LiteLLM_OrganizationTable(LiteLLMPydanticObjectBase):
updated_by: str


class LiteLLM_OrganizationTableUpdate(LiteLLMPydanticObjectBase):
"""Represents user-controllable params for a LiteLLM_OrganizationTable record"""

organization_id: Optional[str] = None
organization_alias: Optional[str] = None
budget_id: Optional[str] = None
spend: Optional[float] = None
metadata: Optional[dict] = None
models: Optional[List[str]] = None
updated_by: Optional[str] = None


class LiteLLM_OrganizationTableWithMembers(LiteLLM_OrganizationTable):
"""Returned by the /organization/info endpoint and /organization/list endpoint"""

Expand Down Expand Up @@ -2097,8 +2121,26 @@ class OrganizationMemberDeleteRequest(MemberDeleteRequest):
organization_id: str


ROLES_WITHIN_ORG = [
LitellmUserRoles.ORG_ADMIN,
LitellmUserRoles.INTERNAL_USER,
LitellmUserRoles.INTERNAL_USER_VIEW_ONLY,
]


class OrganizationMemberUpdateRequest(OrganizationMemberDeleteRequest):
max_budget_in_organization: float
max_budget_in_organization: Optional[float] = None
role: Optional[LitellmUserRoles] = None

@field_validator("role")
def validate_role(
cls, value: Optional[LitellmUserRoles]
) -> Optional[LitellmUserRoles]:
if value is not None and value not in ROLES_WITHIN_ORG:
raise ValueError(
f"Invalid role. Must be one of: {[role.value for role in ROLES_WITHIN_ORG]}"
)
return value


class OrganizationMemberUpdateResponse(MemberUpdateResponse):
Expand Down
Loading

0 comments on commit b4057bc

Please sign in to comment.