mirror of
https://github.com/tiennm99/litellm.git
synced 2026-07-20 00:18:51 +00:00
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:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 ####
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user