fix(usage.tsx): make separate call for top api keys

This commit is contained in:
Krrish Dholakia 2024-02-28 15:37:48 -08:00
parent f7a2d3faef
commit d9862520bc
3 changed files with 178 additions and 40 deletions

View file

@ -4054,7 +4054,7 @@ async def view_spend_logs(
) )
async def global_spend_logs(): async def global_spend_logs():
""" """
[BETA] This is a beta endpoint. [BETA] This is a beta endpoint. It will change.
Use this to get global spend (spend per day for last 30d). Admin-only endpoint Use this to get global spend (spend per day for last 30d). Admin-only endpoint
@ -4069,6 +4069,61 @@ async def global_spend_logs():
return response return response
@router.get(
"/global/spend/keys",
tags=["Budget & Spend Tracking"],
dependencies=[Depends(user_api_key_auth)],
)
async def global_spend_keys(
limit: int = fastapi.Query(
default=None,
description="Number of keys to get. Will return Top 'n' keys.",
)
):
"""
[BETA] This is a beta endpoint. It will change.
Use this to get the top 'n' keys with the highest spend, ordered by spend.
"""
global prisma_client
if prisma_client is None:
raise HTTPException(status_code=500, detail={"error": "No db connected"})
sql_query = f"""SELECT * FROM "Last30dKeysBySpend" LIMIT {limit};"""
response = await prisma_client.db.query_raw(query=sql_query)
return response
@router.get(
"/global/spend/models",
tags=["Budget & Spend Tracking"],
dependencies=[Depends(user_api_key_auth)],
)
async def global_spend_models(
limit: int = fastapi.Query(
default=None,
description="Number of models to get. Will return Top 'n' models.",
)
):
"""
[BETA] This is a beta endpoint. It will change.
Use this to get the top 'n' keys with the highest spend, ordered by spend.
"""
global prisma_client
if prisma_client is None:
raise HTTPException(status_code=500, detail={"error": "No db connected"})
sql_query = f"""SELECT * FROM "Last30dModelsBySpend" LIMIT {limit};"""
response = await prisma_client.db.query_raw(query=sql_query)
return response
@router.get( @router.get(
"/daily_metrics", "/daily_metrics",
summary="Get daily spend metrics", summary="Get daily spend metrics",
@ -4085,7 +4140,11 @@ async def view_daily_metrics(
description="Time till which to view key spend", description="Time till which to view key spend",
), ),
): ):
""" """ """
[BETA] This is a beta endpoint. It might change without notice.
Please give feedback - https://github.com/BerriAI/litellm/issues
"""
try: try:
if os.getenv("CLICKHOUSE_HOST") is not None: if os.getenv("CLICKHOUSE_HOST") is not None:
# gettting spend logs from clickhouse # gettting spend logs from clickhouse

View file

@ -314,10 +314,6 @@ export const userSpendLogsCall = async (
) => { ) => {
try { try {
console.log(`user role in spend logs call: ${userRole}`); console.log(`user role in spend logs call: ${userRole}`);
if (userRole == "Admin") {
return await adminSpendLogsCall(accessToken);
}
let url = proxyBaseUrl ? `${proxyBaseUrl}/spend/logs` : `/spend/logs`; let url = proxyBaseUrl ? `${proxyBaseUrl}/spend/logs` : `/spend/logs`;
if (userRole == "App Owner") { if (userRole == "App Owner") {
url = `${url}/?user_id=${userID}&start_date=${startTime}&end_date=${endTime}`; url = `${url}/?user_id=${userID}&start_date=${startTime}&end_date=${endTime}`;
@ -378,6 +374,66 @@ export const adminSpendLogsCall = async (accessToken: String) => {
} }
}; };
export const adminTopKeysCall = async (accessToken: String) => {
try {
let url = proxyBaseUrl
? `${proxyBaseUrl}/global/spend/keys?limit=5`
: `/global/spend/keys?limit=5`;
message.info("Making spend keys request");
const response = await fetch(url, {
method: "GET",
headers: {
Authorization: `Bearer ${accessToken}`,
"Content-Type": "application/json",
},
});
if (!response.ok) {
const errorData = await response.text();
message.error(errorData);
throw new Error("Network response was not ok");
}
const data = await response.json();
console.log(data);
message.success("Spend Logs received");
return data;
} catch (error) {
console.error("Failed to create key:", error);
throw error;
}
};
export const adminTopModelsCall = async (accessToken: String) => {
try {
let url = proxyBaseUrl
? `${proxyBaseUrl}/global/spend/models?limit=5`
: `/global/spend/models?limit=5`;
message.info("Making spend models request");
const response = await fetch(url, {
method: "GET",
headers: {
Authorization: `Bearer ${accessToken}`,
"Content-Type": "application/json",
},
});
if (!response.ok) {
const errorData = await response.text();
message.error(errorData);
throw new Error("Network response was not ok");
}
const data = await response.json();
console.log(data);
message.success("Spend Logs received");
return data;
} catch (error) {
console.error("Failed to create key:", error);
throw error;
}
};
export const keyInfoCall = async (accessToken: String, keys: String[]) => { export const keyInfoCall = async (accessToken: String, keys: String[]) => {
try { try {
let url = proxyBaseUrl ? `${proxyBaseUrl}/v2/key/info` : `/v2/key/info`; let url = proxyBaseUrl ? `${proxyBaseUrl}/v2/key/info` : `/v2/key/info`;

View file

@ -6,6 +6,8 @@ import {
userSpendLogsCall, userSpendLogsCall,
keyInfoCall, keyInfoCall,
adminSpendLogsCall, adminSpendLogsCall,
adminTopKeysCall,
adminTopModelsCall,
} from "./networking"; } from "./networking";
import { start } from "repl"; import { start } from "repl";
@ -168,40 +170,61 @@ const UsagePage: React.FC<UsagePageProps> = ({
if (accessToken && token && userRole && userID) { if (accessToken && token && userRole && userID) {
const fetchData = async () => { const fetchData = async () => {
try { try {
await userSpendLogsCall( /**
accessToken, * If user is Admin - query the global views endpoints
token, * If user is App Owner - use the normal spend logs call
userRole, */
userID, console.log(`user role: ${userRole}`);
startTime, if (userRole == "Admin") {
endTime const overall_spend = await adminSpendLogsCall(accessToken);
).then(async (response) => { setKeySpendData(overall_spend);
console.log("result from spend logs call", response); const top_keys = await adminTopKeysCall(accessToken);
if ("daily_spend" in response) { const filtered_keys = top_keys.map((k: any) => ({
// this is from clickhouse analytics key: (k["key_name"] || k["key_alias"] || k["api_key"]).substring(
// 0,
let daily_spend = response["daily_spend"]; 7
console.log("daily spend", daily_spend); ),
setKeySpendData(daily_spend); spend: k["total_spend"],
let topApiKeys = response.top_api_keys; }));
setTopKeys(topApiKeys); setTopKeys(filtered_keys);
} else { const top_models = await adminTopModelsCall(accessToken);
// const topKeysResponse = await keyInfoCall( } else if (userRole == "App Owner") {
// accessToken, await userSpendLogsCall(
// getTopKeys(response) accessToken,
// ); token,
// const filtered_keys = topKeysResponse["info"].map((k: any) => ({ userRole,
// key: (k["key_name"] || k["key_alias"] || k["token"]).substring( userID,
// 0, startTime,
// 7 endTime
// ), ).then(async (response) => {
// spend: k["spend"], console.log("result from spend logs call", response);
// })); if ("daily_spend" in response) {
// setTopKeys(filtered_keys); // this is from clickhouse analytics
// setTopUsers(getTopUsers(response)); //
setKeySpendData(response); 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"] ||
k["token"]
).substring(0, 7),
spend: k["spend"],
}));
setTopKeys(filtered_keys);
setTopUsers(getTopUsers(response));
setKeySpendData(response);
}
});
}
} catch (error) { } catch (error) {
console.error("There was an error fetching the data", error); console.error("There was an error fetching the data", error);
// Optionally, update your UI to reflect the error state here as well // Optionally, update your UI to reflect the error state here as well