Merge pull request #2705 from BerriAI/litellm_permissions_table

enable new `/team/disable` endpoint
This commit is contained in:
Krish Dholakia 2024-03-26 18:47:34 -07:00 committed by GitHub
commit e266142d2b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 65 additions and 6 deletions

View file

@ -82,6 +82,8 @@ class LiteLLMRoutes(enum.Enum):
"/team/update", "/team/update",
"/team/delete", "/team/delete",
"/team/info", "/team/info",
"/team/block",
"/team/unblock",
# model # model
"/model/new", "/model/new",
"/model/update", "/model/update",
@ -396,6 +398,7 @@ class TeamBase(LiteLLMBase):
rpm_limit: Optional[int] = None rpm_limit: Optional[int] = None
max_budget: Optional[float] = None max_budget: Optional[float] = None
models: list = [] models: list = []
blocked: bool = False
class NewTeamRequest(TeamBase): class NewTeamRequest(TeamBase):
@ -436,6 +439,10 @@ class DeleteTeamRequest(LiteLLMBase):
team_ids: List[str] # required team_ids: List[str] # required
class BlockTeamRequest(LiteLLMBase):
team_id: str # required
class LiteLLM_TeamTable(TeamBase): class LiteLLM_TeamTable(TeamBase):
spend: Optional[float] = None spend: Optional[float] = None
max_parallel_requests: Optional[int] = None max_parallel_requests: Optional[int] = None

View file

@ -30,12 +30,17 @@ def common_checks(
""" """
Common checks across jwt + key-based auth. Common checks across jwt + key-based auth.
1. If user can call model 1. If team is blocked
2. If user is in budget 2. If team can call model
3. If end_user ('user' passed to /chat/completions, /embeddings endpoint) is in budget 3. If team is in budget
4. If end_user ('user' passed to /chat/completions, /embeddings endpoint) is in budget
""" """
_model = request_body.get("model", None) _model = request_body.get("model", None)
# 1. If user can call model if team_object.blocked == True:
raise Exception(
f"Team={team_object.team_id} is blocked. Update via `/team/unblock` if your admin."
)
# 2. If user can call model
if ( if (
_model is not None _model is not None
and len(team_object.models) > 0 and len(team_object.models) > 0
@ -44,7 +49,7 @@ def common_checks(
raise Exception( raise Exception(
f"Team={team_object.team_id} not allowed to call model={_model}. Allowed team models = {team_object.models}" f"Team={team_object.team_id} not allowed to call model={_model}. Allowed team models = {team_object.models}"
) )
# 2. If team is in budget # 3. If team is in budget
if ( if (
team_object.max_budget is not None team_object.max_budget is not None
and team_object.spend is not None and team_object.spend is not None
@ -53,7 +58,7 @@ def common_checks(
raise Exception( raise Exception(
f"Team={team_object.team_id} over budget. Spend={team_object.spend}, Budget={team_object.max_budget}" f"Team={team_object.team_id} over budget. Spend={team_object.spend}, Budget={team_object.max_budget}"
) )
# 3. If end_user ('user' passed to /chat/completions, /embeddings endpoint) is in budget # 4. If end_user ('user' passed to /chat/completions, /embeddings endpoint) is in budget
if end_user_object is not None and end_user_object.litellm_budget_table is not None: if end_user_object is not None and end_user_object.litellm_budget_table is not None:
end_user_budget = end_user_object.litellm_budget_table.max_budget end_user_budget = end_user_object.litellm_budget_table.max_budget
if end_user_budget is not None and end_user_object.spend > end_user_budget: if end_user_budget is not None and end_user_object.spend > end_user_budget:

View file

@ -6140,6 +6140,50 @@ async def team_info(
) )
@router.post(
"/team/block", tags=["team management"], dependencies=[Depends(user_api_key_auth)]
)
async def block_team(
data: BlockTeamRequest,
user_api_key_dict: UserAPIKeyAuth = Depends(user_api_key_auth),
):
"""
Blocks all calls from keys with this team id.
"""
global prisma_client
if prisma_client is None:
raise Exception("No DB Connected.")
record = await prisma_client.db.litellm_teamtable.update(
where={"team_id": data.team_id}, data={"blocked": True}
)
return record
@router.post(
"/team/unblock", tags=["team management"], dependencies=[Depends(user_api_key_auth)]
)
async def unblock_team(
data: BlockTeamRequest,
user_api_key_dict: UserAPIKeyAuth = Depends(user_api_key_auth),
):
"""
Blocks all calls from keys with this team id.
"""
global prisma_client
if prisma_client is None:
raise Exception("No DB Connected.")
record = await prisma_client.db.litellm_teamtable.update(
where={"team_id": data.team_id}, data={"blocked": False}
)
return record
#### ORGANIZATION MANAGEMENT #### #### ORGANIZATION MANAGEMENT ####

View file

@ -71,6 +71,7 @@ model LiteLLM_TeamTable {
max_parallel_requests Int? max_parallel_requests Int?
tpm_limit BigInt? tpm_limit BigInt?
rpm_limit BigInt? rpm_limit BigInt?
blocked Boolean @default(false)
budget_duration String? budget_duration String?
budget_reset_at DateTime? budget_reset_at DateTime?
blocked Boolean @default(false) blocked Boolean @default(false)

View file

@ -85,6 +85,8 @@ def test_context_window_with_fallbacks(model):
) )
except litellm.ServiceUnavailableError as e: except litellm.ServiceUnavailableError as e:
pass pass
except litellm.APIConnectionError as e:
pass
# for model in litellm.models_by_provider["bedrock"]: # for model in litellm.models_by_provider["bedrock"]: