Merge pull request #2174 from BerriAI/litellm_block_unblock_user_api

Allow end-users to opt out of llm api calls
This commit is contained in:
Krish Dholakia
2024-02-24 11:43:21 -08:00
committed by GitHub
4 changed files with 121 additions and 1 deletions
+24 -1
View File
@@ -1,7 +1,7 @@
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
# ✨ Enterprise Features - Content Moderation, Blocked Users/Keywords
# ✨ Enterprise Features - End-user Opt-out, Content Mod
Features here are behind a commercial license in our `/enterprise` folder. [**See Code**](https://github.com/BerriAI/litellm/tree/main/enterprise)
@@ -167,6 +167,29 @@ curl --location 'http://0.0.0.0:8000/chat/completions' \
:::
### Using via API
**Block all calls for a user id**
```
curl -X POST "http://0.0.0.0:8000/user/block" \
-H "Authorization: Bearer sk-1234" \
-D '{
"user_ids": [<user_id>, ...]
}'
```
**Unblock calls for a user id**
```
curl -X POST "http://0.0.0.0:8000/user/unblock" \
-H "Authorization: Bearer sk-1234" \
-D '{
"user_ids": [<user_id>, ...]
}'
```
## Enable Banned Keywords List
```yaml
+4
View File
@@ -116,6 +116,10 @@ class ModelInfo(LiteLLMBase):
return values
class BlockUsers(LiteLLMBase):
user_ids: List[str] # required
class ModelParams(LiteLLMBase):
model_name: str
litellm_params: dict
+87
View File
@@ -4307,6 +4307,93 @@ async def user_get_requests():
)
@router.post(
"/user/block",
tags=["user management"],
dependencies=[Depends(user_api_key_auth)],
)
async def block_user(data: BlockUsers):
"""
[BETA] Reject calls with this user id
```
curl -X POST "http://0.0.0.0:8000/user/block"
-H "Authorization: Bearer sk-1234"
-D '{
"user_ids": [<user_id>, ...]
}'
```
"""
from litellm.proxy.enterprise.enterprise_hooks.blocked_user_list import (
_ENTERPRISE_BlockedUserList,
)
if not any(isinstance(x, _ENTERPRISE_BlockedUserList) for x in litellm.callbacks):
blocked_user_list = _ENTERPRISE_BlockedUserList()
litellm.callbacks.append(blocked_user_list) # type: ignore
if litellm.blocked_user_list is None:
litellm.blocked_user_list = data.user_ids
elif isinstance(litellm.blocked_user_list, list):
litellm.blocked_user_list = litellm.blocked_user_list + data.user_ids
else:
raise HTTPException(
status_code=500,
detail={
"error": "`blocked_user_list` must be a list or not set. Filepaths can't be updated."
},
)
return {"blocked_users": litellm.blocked_user_list}
@router.post(
"/user/unblock",
tags=["user management"],
dependencies=[Depends(user_api_key_auth)],
)
async def unblock_user(data: BlockUsers):
"""
[BETA] Unblock calls with this user id
Example
```
curl -X POST "http://0.0.0.0:8000/user/unblock"
-H "Authorization: Bearer sk-1234"
-D '{
"user_ids": [<user_id>, ...]
}'
```
"""
from litellm.proxy.enterprise.enterprise_hooks.blocked_user_list import (
_ENTERPRISE_BlockedUserList,
)
if (
not any(isinstance(x, _ENTERPRISE_BlockedUserList) for x in litellm.callbacks)
or litellm.blocked_user_list is None
):
raise HTTPException(
status_code=400,
detail={
"error": "Blocked user check was never set. This call has no effect."
},
)
if isinstance(litellm.blocked_user_list, list):
for id in data.user_ids:
litellm.blocked_user_list.remove(id)
else:
raise HTTPException(
status_code=500,
detail={
"error": "`blocked_user_list` must be set as a list. Filepaths can't be updated."
},
)
return {"blocked_users": litellm.blocked_user_list}
#### TEAM MANAGEMENT ####
+6
View File
@@ -4306,6 +4306,7 @@ def get_optional_params(
or model in litellm.vertex_language_models
or model in litellm.vertex_embedding_models
):
print_verbose(f"(start) INSIDE THE VERTEX AI OPTIONAL PARAM BLOCK")
## check if unsupported param passed in
supported_params = [
"temperature",
@@ -4339,6 +4340,9 @@ def get_optional_params(
optional_params["tools"] = [
generative_models.Tool(function_declarations=gtool_func_declarations)
]
print_verbose(
f"(end) INSIDE THE VERTEX AI OPTIONAL PARAM BLOCK - optional_params: {optional_params}"
)
elif custom_llm_provider == "sagemaker":
## check if unsupported param passed in
supported_params = ["stream", "temperature", "max_tokens", "top_p", "stop", "n"]
@@ -4754,6 +4758,7 @@ def get_optional_params(
extra_body # openai client supports `extra_body` param
)
else: # assume passing in params for openai/azure openai
print_verbose(f"UNMAPPED PROVIDER, ASSUMING IT'S OPENAI/AZUREs")
supported_params = [
"functions",
"function_call",
@@ -4829,6 +4834,7 @@ def get_optional_params(
for k in passed_params.keys():
if k not in default_params.keys():
optional_params[k] = passed_params[k]
print_verbose(f"Final returned optional params: {optional_params}")
return optional_params