From d3f76e33e4f5d4ef8d2a415038a1fa771dc8b2e6 Mon Sep 17 00:00:00 2001 From: Ishaan Jaff Date: Mon, 13 May 2024 16:36:21 -0700 Subject: [PATCH 1/7] ui - clean up edit team input box --- ui/litellm-dashboard/src/components/teams.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/litellm-dashboard/src/components/teams.tsx b/ui/litellm-dashboard/src/components/teams.tsx index d22789420..9e5758a28 100644 --- a/ui/litellm-dashboard/src/components/teams.tsx +++ b/ui/litellm-dashboard/src/components/teams.tsx @@ -129,7 +129,7 @@ const Team: React.FC = ({ name="team_alias" rules={[{ required: true, message: "Please input a team name" }]} > - + Date: Mon, 13 May 2024 17:13:48 -0700 Subject: [PATCH 2/7] backend - show spend per tag by time --- litellm/proxy/proxy_server.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/litellm/proxy/proxy_server.py b/litellm/proxy/proxy_server.py index ec708d5f2..6388bd5fd 100644 --- a/litellm/proxy/proxy_server.py +++ b/litellm/proxy/proxy_server.py @@ -5563,6 +5563,13 @@ async def global_view_spend_tags( f"Database not connected. Connect a database to your proxy - https://docs.litellm.ai/docs/simple_proxy#managing-auth---virtual-keys" ) + if end_date is None or start_date is None: + raise ProxyException( + message="Please provide start_date and end_date", + type="bad_request", + param=None, + code=status.HTTP_400_BAD_REQUEST, + ) response = await ui_get_spend_by_tags( start_date=start_date, end_date=end_date, prisma_client=prisma_client ) From 5845d6f9580c91219656826cfac586a21a35781e Mon Sep 17 00:00:00 2001 From: Ishaan Jaff Date: Mon, 13 May 2024 17:15:04 -0700 Subject: [PATCH 3/7] feat - filter tags by startTime and endTime --- ui/litellm-dashboard/src/components/networking.tsx | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/ui/litellm-dashboard/src/components/networking.tsx b/ui/litellm-dashboard/src/components/networking.tsx index 4a629ed47..1ec131f72 100644 --- a/ui/litellm-dashboard/src/components/networking.tsx +++ b/ui/litellm-dashboard/src/components/networking.tsx @@ -655,11 +655,20 @@ export const teamSpendLogsCall = async (accessToken: String) => { }; -export const tagsSpendLogsCall = async (accessToken: String) => { +export const tagsSpendLogsCall = async ( + accessToken: String, + startTime: String | undefined, + endTime: String | undefined + ) => { try { - const url = proxyBaseUrl + let url = proxyBaseUrl ? `${proxyBaseUrl}/global/spend/tags` : `/global/spend/tags`; + + if (startTime && endTime) { + url = `${url}?start_date=${startTime}&end_date=${endTime}` + } + console.log("in tagsSpendLogsCall:", url); const response = await fetch(`${url}`, { method: "GET", From 51961387a2b7d915c4fb481fc0c889b17e9fd0db Mon Sep 17 00:00:00 2001 From: Ishaan Jaff Date: Mon, 13 May 2024 17:15:25 -0700 Subject: [PATCH 4/7] ui - filter tags by starttime and endtime --- enterprise/utils.py | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/enterprise/utils.py b/enterprise/utils.py index 05bd7dac6..481e663be 100644 --- a/enterprise/utils.py +++ b/enterprise/utils.py @@ -1,6 +1,7 @@ # Enterprise Proxy Util Endpoints from litellm._logging import verbose_logger import collections +from datetime import datetime async def get_spend_by_tags(start_date=None, end_date=None, prisma_client=None): @@ -18,19 +19,25 @@ async def get_spend_by_tags(start_date=None, end_date=None, prisma_client=None): return response -async def ui_get_spend_by_tags(start_date=None, end_date=None, prisma_client=None): - response = await prisma_client.db.query_raw( - """ +async def ui_get_spend_by_tags(start_date: str, end_date: str, prisma_client): + + sql_query = """ SELECT jsonb_array_elements_text(request_tags) AS individual_request_tag, DATE(s."startTime") AS spend_date, COUNT(*) AS log_count, SUM(spend) AS total_spend FROM "LiteLLM_SpendLogs" s - WHERE s."startTime" >= current_date - interval '30 days' + WHERE + DATE(s."startTime") >= $1::date + AND DATE(s."startTime") <= $2::date GROUP BY individual_request_tag, spend_date ORDER BY spend_date; - """ + """ + response = await prisma_client.db.query_raw( + sql_query, + start_date, + end_date, ) # print("tags - spend") From 5dfa0ed1960966d3ffbe3bc6cbb9908efb024f1d Mon Sep 17 00:00:00 2001 From: Ishaan Jaff Date: Mon, 13 May 2024 17:15:39 -0700 Subject: [PATCH 5/7] filter tags usage by date --- ui/litellm-dashboard/src/components/usage.tsx | 24 ++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/ui/litellm-dashboard/src/components/usage.tsx b/ui/litellm-dashboard/src/components/usage.tsx index 54376410a..6e298a76e 100644 --- a/ui/litellm-dashboard/src/components/usage.tsx +++ b/ui/litellm-dashboard/src/components/usage.tsx @@ -153,6 +153,19 @@ const UsagePage: React.FC = ({ console.log("End user data updated successfully", newTopUserData); setTopUsers(newTopUserData); + } + + const updateTagSpendData = async (startTime: Date | undefined, endTime: Date | undefined) => { + if (!startTime || !endTime || !accessToken) { + return; + } + + let top_tags = await tagsSpendLogsCall(accessToken, startTime.toISOString(), endTime.toISOString()); + setTopTagsData(top_tags.top_10_tags); + console.log("Tag spend data updated successfully"); + + + } function formatDate(date: Date) { @@ -218,7 +231,7 @@ const UsagePage: React.FC = ({ setTotalSpendPerTeam(total_spend_per_team); //get top tags - const top_tags = await tagsSpendLogsCall(accessToken); + const top_tags = await tagsSpendLogsCall(accessToken, dateValue.from?.toISOString(), dateValue.to?.toISOString()); setTopTagsData(top_tags.top_10_tags); // get spend per end-user @@ -459,6 +472,15 @@ const UsagePage: React.FC = ({ + { + setDateValue(value); + updateTagSpendData(value.from, value.to); // Call updateModelMetrics with the new date range + }} + /> Spend Per Tag - Last 30 Days From 052cfeb81030da27e4b1ea97f6622f03f902cbf5 Mon Sep 17 00:00:00 2001 From: Ishaan Jaff Date: Mon, 13 May 2024 17:31:18 -0700 Subject: [PATCH 6/7] ui - how spend per tag in bar chart --- ui/litellm-dashboard/src/components/usage.tsx | 45 ++++++------------- 1 file changed, 13 insertions(+), 32 deletions(-) diff --git a/ui/litellm-dashboard/src/components/usage.tsx b/ui/litellm-dashboard/src/components/usage.tsx index 6e298a76e..6f03c2960 100644 --- a/ui/litellm-dashboard/src/components/usage.tsx +++ b/ui/litellm-dashboard/src/components/usage.tsx @@ -161,7 +161,7 @@ const UsagePage: React.FC = ({ } let top_tags = await tagsSpendLogsCall(accessToken, startTime.toISOString(), endTime.toISOString()); - setTopTagsData(top_tags.top_10_tags); + setTopTagsData(top_tags.spend_per_tag); console.log("Tag spend data updated successfully"); @@ -232,7 +232,7 @@ const UsagePage: React.FC = ({ //get top tags const top_tags = await tagsSpendLogsCall(accessToken, dateValue.from?.toISOString(), dateValue.to?.toISOString()); - setTopTagsData(top_tags.top_10_tags); + setTopTagsData(top_tags.spend_per_tag); // get spend per end-user let spend_user_call = await adminTopEndUsersCall(accessToken, null, undefined, undefined); @@ -483,36 +483,17 @@ const UsagePage: React.FC = ({ /> - Spend Per Tag - Last 30 Days - Get Started Tracking cost per tag here - - - - Tag - Spend - Requests - - - - {topTagsData.map((tag) => ( - - {tag.name} - {tag.value} - {tag.log_count} - - ))} - -
- {/* */} + Spend Per Tag + Get Started Tracking cost per tag here + + +
From fa4dcbd37c65dd7ae66e0c0cb3e5f1607e8d2469 Mon Sep 17 00:00:00 2001 From: Ishaan Jaff Date: Mon, 13 May 2024 17:31:29 -0700 Subject: [PATCH 7/7] ui - round up spend per tag --- enterprise/utils.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/enterprise/utils.py b/enterprise/utils.py index 481e663be..1b5036e96 100644 --- a/enterprise/utils.py +++ b/enterprise/utils.py @@ -32,7 +32,8 @@ async def ui_get_spend_by_tags(start_date: str, end_date: str, prisma_client): DATE(s."startTime") >= $1::date AND DATE(s."startTime") <= $2::date GROUP BY individual_request_tag, spend_date - ORDER BY spend_date; + ORDER BY spend_date + LIMIT 100; """ response = await prisma_client.db.query_raw( sql_query, @@ -56,15 +57,18 @@ async def ui_get_spend_by_tags(start_date: str, end_date: str, prisma_client): # convert to ui format ui_tags = [] for tag in sorted_tags: + current_spend = tag[1] + if current_spend is not None and isinstance(current_spend, float): + current_spend = round(current_spend, 4) ui_tags.append( { "name": tag[0], - "value": tag[1], + "spend": current_spend, "log_count": total_requests_per_tag[tag[0]], } ) - return {"top_10_tags": ui_tags} + return {"spend_per_tag": ui_tags} async def view_spend_logs_from_clickhouse(