import { BarChart, BarList, Card, Title, Table, TableHead, TableHeaderCell, TableRow, TableCell, TableBody, Metric } from "@tremor/react"; import React, { useState, useEffect } from "react"; import ViewUserSpend from "./view_user_spend"; import { Grid, Col, Text, LineChart, TabPanel, TabPanels, TabGroup, TabList, Tab, Select, SelectItem } from "@tremor/react"; import { userSpendLogsCall, keyInfoCall, adminSpendLogsCall, adminTopKeysCall, adminTopModelsCall, teamSpendLogsCall, tagsSpendLogsCall, modelMetricsCall, modelAvailableCall, modelInfoCall, } from "./networking"; import { start } from "repl"; interface UsagePageProps { accessToken: string | null; token: string | null; userRole: string | null; userID: string | null; } type CustomTooltipTypeBar = { payload: any; active: boolean | undefined; label: any; }; const customTooltip = (props: CustomTooltipTypeBar) => { const { payload, active } = props; if (!active || !payload) return null; const value = payload[0].payload; const date = value["startTime"]; const model_values = value["models"]; // Convert the object into an array of key-value pairs const entries: [string, number][] = Object.entries(model_values).map( ([key, value]) => [key, value as number] ); // Type assertion to specify the value as number // Sort the array based on the float value in descending order entries.sort((a, b) => b[1] - a[1]); // Get the top 5 key-value pairs const topEntries = entries.slice(0, 5); return (
{date} {topEntries.map(([key, value]) => (

{key} {":"} {" "} {value ? (value < 0.01 ? "<$0.01" : value.toFixed(2)) : ""}

))}
); }; function getTopKeys(data: Array<{ [key: string]: unknown }>): any[] { const spendKeys: { key: string; spend: unknown }[] = []; data.forEach((dict) => { Object.entries(dict).forEach(([key, value]) => { if ( key !== "spend" && key !== "startTime" && key !== "models" && key !== "users" ) { spendKeys.push({ key, spend: value }); } }); }); spendKeys.sort((a, b) => Number(b.spend) - Number(a.spend)); const topKeys = spendKeys.slice(0, 5).map((k) => k.key); console.log(`topKeys: ${Object.keys(topKeys[0])}`); return topKeys; } type DataDict = { [key: string]: unknown }; type UserData = { user_id: string; spend: number }; function getTopUsers(data: Array): UserData[] { const userSpend: { [key: string]: number } = {}; data.forEach((dict) => { const payload: DataDict = dict["users"] as DataDict; Object.entries(payload).forEach(([user_id, value]) => { if ( user_id === "" || user_id === undefined || user_id === null || user_id == "None" ) { return; } if (!userSpend[user_id]) { userSpend[user_id] = 0; } userSpend[user_id] += value as number; }); }); const spendUsers: UserData[] = Object.entries(userSpend).map( ([user_id, spend]) => ({ user_id, spend, }) ); spendUsers.sort((a, b) => b.spend - a.spend); const topKeys = spendUsers.slice(0, 5); console.log(`topKeys: ${Object.values(topKeys[0])}`); return topKeys; } const UsagePage: React.FC = ({ accessToken, token, userRole, userID, }) => { const currentDate = new Date(); const [keySpendData, setKeySpendData] = useState([]); const [topKeys, setTopKeys] = useState([]); const [topModels, setTopModels] = useState([]); const [topUsers, setTopUsers] = useState([]); const [teamSpendData, setTeamSpendData] = useState([]); const [topTagsData, setTopTagsData] = useState([]); const [uniqueTeamIds, setUniqueTeamIds] = useState([]); const [totalSpendPerTeam, setTotalSpendPerTeam] = useState([]); const firstDay = new Date( currentDate.getFullYear(), currentDate.getMonth(), 1 ); const lastDay = new Date( currentDate.getFullYear(), currentDate.getMonth() + 1, 0 ); let startTime = formatDate(firstDay); let endTime = formatDate(lastDay); function formatDate(date: Date) { const year = date.getFullYear(); let month = date.getMonth() + 1; // JS month index starts from 0 let day = date.getDate(); // Pad with 0 if month or day is less than 10 const monthStr = month < 10 ? "0" + month : month; const dayStr = day < 10 ? "0" + day : day; return `${year}-${monthStr}-${dayStr}`; } console.log(`Start date is ${startTime}`); console.log(`End date is ${endTime}`); const valueFormatter = (number: number) => `$ ${new Intl.NumberFormat("us").format(number).toString()}`; useEffect(() => { if (accessToken && token && userRole && userID) { const fetchData = async () => { try { /** * If user is Admin - query the global views endpoints * If user is App Owner - use the normal spend logs call */ console.log(`user role: ${userRole}`); if (userRole == "Admin" || userRole == "Admin Viewer") { const overall_spend = await adminSpendLogsCall(accessToken); setKeySpendData(overall_spend); const top_keys = await adminTopKeysCall(accessToken); const filtered_keys = top_keys.map((k: any) => ({ key: (k["key_name"] || k["key_alias"] || k["api_key"]).substring( 0, 10 ), spend: k["total_spend"], })); setTopKeys(filtered_keys); const top_models = await adminTopModelsCall(accessToken); const filtered_models = top_models.map((k: any) => ({ key: k["model"], spend: k["total_spend"], })); setTopModels(filtered_models); const teamSpend = await teamSpendLogsCall(accessToken); console.log("teamSpend", teamSpend); setTeamSpendData(teamSpend.daily_spend); setUniqueTeamIds(teamSpend.teams) let total_spend_per_team = teamSpend.total_spend_per_team; // in total_spend_per_team, replace null team_id with "" and replace null total_spend with 0 total_spend_per_team = total_spend_per_team.map((tspt: any) => { tspt["name"] = tspt["team_id"] || ""; tspt["value"] = tspt["total_spend"] || 0; return tspt; }) setTotalSpendPerTeam(total_spend_per_team); //get top tags const top_tags = await tagsSpendLogsCall(accessToken); setTopTagsData(top_tags.top_10_tags); } else if (userRole == "App Owner") { await userSpendLogsCall( accessToken, token, userRole, userID, startTime, endTime ).then(async (response) => { console.log("result from spend logs call", response); if ("daily_spend" in response) { // this is from clickhouse analytics // let daily_spend = response["daily_spend"]; console.log("daily spend", daily_spend); setKeySpendData(daily_spend); let topApiKeys = response.top_api_keys; setTopKeys(topApiKeys); } else { const topKeysResponse = await keyInfoCall( accessToken, getTopKeys(response) ); const filtered_keys = topKeysResponse["info"].map((k: any) => ({ key: ( k["key_name"] || k["key_alias"] ).substring(0, 10), spend: k["spend"], })); setTopKeys(filtered_keys); setTopUsers(getTopUsers(response)); setKeySpendData(response); } }); } } catch (error) { console.error("There was an error fetching the data", error); // Optionally, update your UI to reflect the error state here as well } }; fetchData(); } }, [accessToken, token, userRole, userID, startTime, endTime]); return (
All Up Team Based Usage Tag Based Usage Monthly Spend Top API Keys Top Users Top Models Total Spend Per Team Daily Spend Per Team 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} ))}
{/* */}
); }; export default UsagePage;