Merge pull request #3624 from BerriAI/litellm_ui_cleanup_2

[UI] Filter Tag Spend by Date + Show Bar Chart
This commit is contained in:
Ishaan Jaff 2024-05-13 17:33:43 -07:00 committed by GitHub
commit 067749805b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 73 additions and 43 deletions

View file

@ -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(

View file

@ -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
)

View file

@ -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",

View file

@ -129,7 +129,7 @@ const Team: React.FC<TeamProps> = ({
name="team_alias"
rules={[{ required: true, message: "Please input a team name" }]}
>
<Input />
<TextInput />
</Form.Item>
<Form.Item label="Models" name="models">
<Select2

View file

@ -153,6 +153,19 @@ const UsagePage: React.FC<UsagePageProps> = ({
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<UsagePageProps> = ({
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<UsagePageProps> = ({
<TabPanel>
<Grid numItems={2} className="gap-2 h-[75vh] w-full mb-4">
<Col numColSpan={2}>
<DateRangePicker
className="mb-4"
enableSelect={true}
value={dateValue}
onValueChange={(value) => {
setDateValue(value);
updateTagSpendData(value.from, value.to); // Call updateModelMetrics with the new date range
}}
/>
<Card>
<Title>Spend Per Tag - Last 30 Days</Title>
<Text>Get Started Tracking cost per tag <a href="https://docs.litellm.ai/docs/proxy/enterprise#tracking-spend-for-custom-tags" target="_blank">here</a></Text>
<Table>
<TableHead>
<TableRow>
<TableHeaderCell>Tag</TableHeaderCell>
<TableHeaderCell>Spend</TableHeaderCell>
<TableHeaderCell>Requests</TableHeaderCell>
</TableRow>
</TableHead>
<TableBody>
{topTagsData.map((tag) => (
<TableRow key={tag.name}>
<TableCell>{tag.name}</TableCell>
<TableCell>{tag.value}</TableCell>
<TableCell>{tag.log_count}</TableCell>
</TableRow>
))}
</TableBody>
</Table>
{/* <BarChart
className="h-72"
data={teamSpendData}
showLegend={true}
index="date"
categories={uniqueTeamIds}
yAxisWidth={80}
<Title>Spend Per Tag</Title>
<Text>Get Started Tracking cost per tag <a className="text-blue-500" href="https://docs.litellm.ai/docs/proxy/enterprise#tracking-spend-for-custom-tags" target="_blank">here</a></Text>
<BarChart
className="h-72"
data={topTagsData}
index="name"
categories={["spend"]}
colors={["blue"]}
>
stack={true}
/> */}
</BarChart>
</Card>
</Col>
<Col numColSpan={2}>