diff --git a/enterprise/utils.py b/enterprise/utils.py index 05bd7dac6..1b5036e96 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,26 @@ 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; - """ + ORDER BY spend_date + LIMIT 100; + """ + response = await prisma_client.db.query_raw( + sql_query, + start_date, + end_date, ) # print("tags - spend") @@ -49,15 +57,18 @@ async def ui_get_spend_by_tags(start_date=None, end_date=None, prisma_client=Non # 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( 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 ) 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", 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" }]} > - + = ({ 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.spend_per_tag); + console.log("Tag spend data updated successfully"); + + + } function formatDate(date: Date) { @@ -218,8 +231,8 @@ const UsagePage: React.FC = ({ setTotalSpendPerTeam(total_spend_per_team); //get top tags - const top_tags = await tagsSpendLogsCall(accessToken); - setTopTagsData(top_tags.top_10_tags); + const top_tags = await tagsSpendLogsCall(accessToken, dateValue.from?.toISOString(), dateValue.to?.toISOString()); + setTopTagsData(top_tags.spend_per_tag); // get spend per end-user let spend_user_call = await adminTopEndUsersCall(accessToken, null, undefined, undefined); @@ -459,38 +472,28 @@ const UsagePage: React.FC = ({ + { + setDateValue(value); + updateTagSpendData(value.from, value.to); // Call updateModelMetrics with the new date range + }} + /> - 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 + + +