forked from phoenix/litellm-mirror
Merge pull request #2255 from BerriAI/litellm_admin_ui_user_panel_load_time_high
[FEAT] proxy add pagination on /user/info endpoint (Admin UI does not load all users)
This commit is contained in:
commit
e044d6332f
4 changed files with 91 additions and 8 deletions
|
@ -2,7 +2,7 @@ import Image from '@theme/IdealImage';
|
||||||
import Tabs from '@theme/Tabs';
|
import Tabs from '@theme/Tabs';
|
||||||
import TabItem from '@theme/TabItem';
|
import TabItem from '@theme/TabItem';
|
||||||
|
|
||||||
# 🔑 [BETA] Proxy UI
|
# [BETA] Proxy UI
|
||||||
### **Create + delete keys through a UI**
|
### **Create + delete keys through a UI**
|
||||||
|
|
||||||
[Let users create their own keys](#setup-ssoauth-for-ui)
|
[Let users create their own keys](#setup-ssoauth-for-ui)
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# Virtual Keys, Users
|
# 🔑 Virtual Keys, Users
|
||||||
Track Spend, Set budgets and create virtual keys for the proxy
|
Track Spend, Set budgets and create virtual keys for the proxy
|
||||||
|
|
||||||
Grant other's temporary access to your proxy, with keys that expire after a set duration.
|
Grant other's temporary access to your proxy, with keys that expire after a set duration.
|
||||||
|
@ -343,18 +343,83 @@ A key will be generated for the new user created
|
||||||
"key_name": null,
|
"key_name": null,
|
||||||
"expires": null
|
"expires": null
|
||||||
}
|
}
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Request Params:
|
|
||||||
- keys: List[str] - List of keys to delete
|
## /user/info
|
||||||
|
|
||||||
|
### Request
|
||||||
|
|
||||||
|
#### View all Users
|
||||||
|
If you're trying to view all users, we recommend using pagination with the following args
|
||||||
|
- `view_all=true`
|
||||||
|
- `page=0` Optional(int) min = 0, default=0
|
||||||
|
- `page_size=25` Optional(int) min = 1, default = 25
|
||||||
|
```shell
|
||||||
|
curl -X GET "http://0.0.0.0:4000/user/info?view_all=true&page=0&page_size=25" -H "Authorization: Bearer sk-1234"
|
||||||
|
```
|
||||||
|
|
||||||
|
#### View specific user_id
|
||||||
|
```shell
|
||||||
|
curl -X GET "http://0.0.0.0:4000/user/info?user_id=228da235-eef0-4c30-bf53-5d6ac0d278c2" -H "Authorization: Bearer sk-1234"
|
||||||
|
```
|
||||||
|
|
||||||
### Response
|
### Response
|
||||||
|
View user spend, budget, models, keys and teams
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"deleted_keys": ["sk-kdEXbIqZRwEeEiHwdg7sFA"]
|
"user_id": "228da235-eef0-4c30-bf53-5d6ac0d278c2",
|
||||||
|
"user_info": {
|
||||||
|
"user_id": "228da235-eef0-4c30-bf53-5d6ac0d278c2",
|
||||||
|
"team_id": null,
|
||||||
|
"teams": [],
|
||||||
|
"user_role": "app_user",
|
||||||
|
"max_budget": null,
|
||||||
|
"spend": 200000.0,
|
||||||
|
"user_email": null,
|
||||||
|
"models": [],
|
||||||
|
"max_parallel_requests": null,
|
||||||
|
"tpm_limit": null,
|
||||||
|
"rpm_limit": null,
|
||||||
|
"budget_duration": null,
|
||||||
|
"budget_reset_at": null,
|
||||||
|
"allowed_cache_controls": [],
|
||||||
|
"model_spend": {
|
||||||
|
"chatgpt-v-2": 200000
|
||||||
|
},
|
||||||
|
"model_max_budget": {}
|
||||||
|
},
|
||||||
|
"keys": [
|
||||||
|
{
|
||||||
|
"token": "16c337f9df00a0e6472627e39a2ed02e67bc9a8a760c983c4e9b8cad7954f3c0",
|
||||||
|
"key_name": null,
|
||||||
|
"key_alias": null,
|
||||||
|
"spend": 200000.0,
|
||||||
|
"expires": null,
|
||||||
|
"models": [],
|
||||||
|
"aliases": {},
|
||||||
|
"config": {},
|
||||||
|
"user_id": "228da235-eef0-4c30-bf53-5d6ac0d278c2",
|
||||||
|
"team_id": null,
|
||||||
|
"permissions": {},
|
||||||
|
"max_parallel_requests": null,
|
||||||
|
"metadata": {},
|
||||||
|
"tpm_limit": null,
|
||||||
|
"rpm_limit": null,
|
||||||
|
"max_budget": null,
|
||||||
|
"budget_duration": null,
|
||||||
|
"budget_reset_at": null,
|
||||||
|
"allowed_cache_controls": [],
|
||||||
|
"model_spend": {
|
||||||
|
"chatgpt-v-2": 200000
|
||||||
|
},
|
||||||
|
"model_max_budget": {}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"teams": []
|
||||||
}
|
}
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Advanced
|
## Advanced
|
||||||
|
|
|
@ -4329,6 +4329,14 @@ async def user_info(
|
||||||
default=False,
|
default=False,
|
||||||
description="set to true to View all users. When using view_all, don't pass user_id",
|
description="set to true to View all users. When using view_all, don't pass user_id",
|
||||||
),
|
),
|
||||||
|
page: Optional[int] = fastapi.Query(
|
||||||
|
default=0,
|
||||||
|
description="Page number for pagination. Only use when view_all is true",
|
||||||
|
),
|
||||||
|
page_size: Optional[int] = fastapi.Query(
|
||||||
|
default=25,
|
||||||
|
description="Number of items per page. Only use when view_all is true",
|
||||||
|
),
|
||||||
user_api_key_dict: UserAPIKeyAuth = Depends(user_api_key_auth),
|
user_api_key_dict: UserAPIKeyAuth = Depends(user_api_key_auth),
|
||||||
):
|
):
|
||||||
"""
|
"""
|
||||||
|
@ -4350,8 +4358,14 @@ async def user_info(
|
||||||
if user_id is not None:
|
if user_id is not None:
|
||||||
user_info = await prisma_client.get_data(user_id=user_id)
|
user_info = await prisma_client.get_data(user_id=user_id)
|
||||||
elif view_all == True:
|
elif view_all == True:
|
||||||
|
if page is None:
|
||||||
|
page = 0
|
||||||
|
if page_size is None:
|
||||||
|
page_size = 25
|
||||||
|
offset = (page) * page_size # default is 0
|
||||||
|
limit = page_size # default is 10
|
||||||
user_info = await prisma_client.get_data(
|
user_info = await prisma_client.get_data(
|
||||||
table_name="user", query_type="find_all"
|
table_name="user", query_type="find_all", offset=offset, limit=limit
|
||||||
)
|
)
|
||||||
return user_info
|
return user_info
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -641,6 +641,10 @@ class PrismaClient:
|
||||||
query_type: Literal["find_unique", "find_all"] = "find_unique",
|
query_type: Literal["find_unique", "find_all"] = "find_unique",
|
||||||
expires: Optional[datetime] = None,
|
expires: Optional[datetime] = None,
|
||||||
reset_at: Optional[datetime] = None,
|
reset_at: Optional[datetime] = None,
|
||||||
|
offset: Optional[int] = None, # pagination, what row number to start from
|
||||||
|
limit: Optional[
|
||||||
|
int
|
||||||
|
] = None, # pagination, number of rows to getch when find_all==True
|
||||||
):
|
):
|
||||||
try:
|
try:
|
||||||
response: Any = None
|
response: Any = None
|
||||||
|
@ -776,7 +780,7 @@ class PrismaClient:
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
response = await self.db.litellm_usertable.find_many( # type: ignore
|
response = await self.db.litellm_usertable.find_many( # type: ignore
|
||||||
order={"spend": "desc"},
|
order={"spend": "desc"}, take=limit, skip=offset
|
||||||
)
|
)
|
||||||
return response
|
return response
|
||||||
elif table_name == "spend":
|
elif table_name == "spend":
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue