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():
|
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
|
||||||
|
|
|
@ -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`;
|
||||||
|
|
|
@ -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,6 +170,25 @@ const UsagePage: React.FC<UsagePageProps> = ({
|
||||||
if (accessToken && token && userRole && userID) {
|
if (accessToken && token && userRole && userID) {
|
||||||
const fetchData = async () => {
|
const fetchData = async () => {
|
||||||
try {
|
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") {
|
||||||
|
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(
|
await userSpendLogsCall(
|
||||||
accessToken,
|
accessToken,
|
||||||
token,
|
token,
|
||||||
|
@ -186,22 +207,24 @@ const UsagePage: React.FC<UsagePageProps> = ({
|
||||||
let topApiKeys = response.top_api_keys;
|
let topApiKeys = response.top_api_keys;
|
||||||
setTopKeys(topApiKeys);
|
setTopKeys(topApiKeys);
|
||||||
} else {
|
} else {
|
||||||
// const topKeysResponse = await keyInfoCall(
|
const topKeysResponse = await keyInfoCall(
|
||||||
// accessToken,
|
accessToken,
|
||||||
// getTopKeys(response)
|
getTopKeys(response)
|
||||||
// );
|
);
|
||||||
// const filtered_keys = topKeysResponse["info"].map((k: any) => ({
|
const filtered_keys = topKeysResponse["info"].map((k: any) => ({
|
||||||
// key: (k["key_name"] || k["key_alias"] || k["token"]).substring(
|
key: (
|
||||||
// 0,
|
k["key_name"] ||
|
||||||
// 7
|
k["key_alias"] ||
|
||||||
// ),
|
k["token"]
|
||||||
// spend: k["spend"],
|
).substring(0, 7),
|
||||||
// }));
|
spend: k["spend"],
|
||||||
// setTopKeys(filtered_keys);
|
}));
|
||||||
// setTopUsers(getTopUsers(response));
|
setTopKeys(filtered_keys);
|
||||||
|
setTopUsers(getTopUsers(response));
|
||||||
setKeySpendData(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
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue