forked from phoenix/litellm-mirror
fix(usage.tsx): make separate call for top api keys
This commit is contained in:
parent
f7a2d3faef
commit
d9862520bc
3 changed files with 178 additions and 40 deletions
|
@ -4054,7 +4054,7 @@ async def view_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
|
||||
|
||||
|
@ -4069,6 +4069,61 @@ async def global_spend_logs():
|
|||
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(
|
||||
"/daily_metrics",
|
||||
summary="Get daily spend metrics",
|
||||
|
@ -4085,7 +4140,11 @@ async def view_daily_metrics(
|
|||
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:
|
||||
if os.getenv("CLICKHOUSE_HOST") is not None:
|
||||
# gettting spend logs from clickhouse
|
||||
|
|
|
@ -314,10 +314,6 @@ export const userSpendLogsCall = async (
|
|||
) => {
|
||||
try {
|
||||
console.log(`user role in spend logs call: ${userRole}`);
|
||||
if (userRole == "Admin") {
|
||||
return await adminSpendLogsCall(accessToken);
|
||||
}
|
||||
|
||||
let url = proxyBaseUrl ? `${proxyBaseUrl}/spend/logs` : `/spend/logs`;
|
||||
if (userRole == "App Owner") {
|
||||
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[]) => {
|
||||
try {
|
||||
let url = proxyBaseUrl ? `${proxyBaseUrl}/v2/key/info` : `/v2/key/info`;
|
||||
|
|
|
@ -6,6 +6,8 @@ import {
|
|||
userSpendLogsCall,
|
||||
keyInfoCall,
|
||||
adminSpendLogsCall,
|
||||
adminTopKeysCall,
|
||||
adminTopModelsCall,
|
||||
} from "./networking";
|
||||
import { start } from "repl";
|
||||
|
||||
|
@ -168,40 +170,61 @@ const UsagePage: React.FC<UsagePageProps> = ({
|
|||
if (accessToken && token && userRole && userID) {
|
||||
const fetchData = async () => {
|
||||
try {
|
||||
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"] || k["token"]).substring(
|
||||
// 0,
|
||||
// 7
|
||||
// ),
|
||||
// spend: k["spend"],
|
||||
// }));
|
||||
// setTopKeys(filtered_keys);
|
||||
// setTopUsers(getTopUsers(response));
|
||||
setKeySpendData(response);
|
||||
}
|
||||
});
|
||||
/**
|
||||
* 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") {
|
||||
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,
|
||||
7
|
||||
),
|
||||
spend: k["total_spend"],
|
||||
}));
|
||||
setTopKeys(filtered_keys);
|
||||
const top_models = await adminTopModelsCall(accessToken);
|
||||
} 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"] ||
|
||||
k["token"]
|
||||
).substring(0, 7),
|
||||
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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue