mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-08 03:08:45 +00:00
Merge pull request #1803 from BerriAI/litellm_ui_view_usage
[Feat] UI view spend / budget per user
This commit is contained in:
commit
6eb616cf12
4 changed files with 68 additions and 1 deletions
|
|
@ -208,6 +208,7 @@ class UpdateUserRequest(GenerateRequestBase):
|
|||
spend: Optional[float] = None
|
||||
metadata: Optional[dict] = None
|
||||
user_role: Optional[str] = None
|
||||
max_budget: Optional[float] = None
|
||||
|
||||
|
||||
class KeyManagementSystem(enum.Enum):
|
||||
|
|
|
|||
|
|
@ -554,7 +554,6 @@ async def user_api_key_auth(
|
|||
db=custom_db_client,
|
||||
)
|
||||
)
|
||||
|
||||
if (
|
||||
route.startswith("/key/")
|
||||
or route.startswith("/user/")
|
||||
|
|
@ -589,6 +588,11 @@ async def user_api_key_auth(
|
|||
status_code=status.HTTP_403_FORBIDDEN,
|
||||
detail="user not allowed to access this key's info",
|
||||
)
|
||||
elif route == "/user/update":
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_403_FORBIDDEN,
|
||||
detail="only proxy admin can update user settings. Tried calling `/user/update`",
|
||||
)
|
||||
elif route == "/model/info":
|
||||
# /model/info just shows models user has access to
|
||||
pass
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import { userInfoCall } from "./networking";
|
|||
import { Grid, Col, Card, Text } from "@tremor/react";
|
||||
import CreateKey from "./create_key_button";
|
||||
import ViewKeyTable from "./view_key_table";
|
||||
import ViewUserSpend from "./view_user_spend";
|
||||
import EnterProxyUrl from "./enter_proxy_url";
|
||||
import Navbar from "./navbar";
|
||||
import { useSearchParams } from "next/navigation";
|
||||
|
|
@ -14,6 +15,7 @@ const proxyBaseUrl = "http://localhost:4000" // http://localhost:4000
|
|||
|
||||
const UserDashboard = () => {
|
||||
const [data, setData] = useState<null | any[]>(null); // Keep the initialization of state here
|
||||
const [userSpendData, setUserSpendData] = useState<null | any[]>(null);
|
||||
// Assuming useSearchParams() hook exists and works in your setup
|
||||
const searchParams = useSearchParams();
|
||||
const userID = searchParams.get("userID");
|
||||
|
|
@ -71,6 +73,8 @@ const UserDashboard = () => {
|
|||
accessToken,
|
||||
userID
|
||||
);
|
||||
console.log("Response:", response);
|
||||
setUserSpendData(response["user_info"])
|
||||
setData(response["keys"]); // Assuming this is the correct path to your data
|
||||
} catch (error) {
|
||||
console.error("There was an error fetching the data", error);
|
||||
|
|
@ -104,6 +108,10 @@ const UserDashboard = () => {
|
|||
/>
|
||||
<Grid numItems={1} className="gap-0 p-10 h-[75vh] w-full">
|
||||
<Col numColSpan={1}>
|
||||
<ViewUserSpend
|
||||
userID={userID}
|
||||
userSpendData={userSpendData}
|
||||
/>
|
||||
<ViewKeyTable
|
||||
userID={userID}
|
||||
userRole={userRole}
|
||||
|
|
|
|||
54
ui/litellm-dashboard/src/components/view_user_spend.tsx
Normal file
54
ui/litellm-dashboard/src/components/view_user_spend.tsx
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
"use client";
|
||||
import React, { useEffect } from "react";
|
||||
import { keyDeleteCall } from "./networking";
|
||||
import { StatusOnlineIcon, TrashIcon } from "@heroicons/react/outline";
|
||||
import { DonutChart } from "@tremor/react";
|
||||
import {
|
||||
Badge,
|
||||
Card,
|
||||
Table,
|
||||
Metric,
|
||||
TableBody,
|
||||
TableCell,
|
||||
TableHead,
|
||||
TableHeaderCell,
|
||||
TableRow,
|
||||
Text,
|
||||
Title,
|
||||
Icon,
|
||||
} from "@tremor/react";
|
||||
|
||||
|
||||
// Define the props type
|
||||
interface UserSpendData {
|
||||
spend: number; // Adjust the type accordingly based on your data
|
||||
max_budget?: number | null; // Optional property with a default of null
|
||||
// Add other properties if needed
|
||||
}
|
||||
interface ViewUserSpendProps {
|
||||
userID: string | null;
|
||||
userSpendData: UserSpendData | null; // Use the UserSpendData interface here
|
||||
}
|
||||
const ViewUserSpend: React.FC<ViewUserSpendProps> = ({ userID, userSpendData }) => {
|
||||
console.log("User SpendData:", userSpendData);
|
||||
const spend = userSpendData?.spend;
|
||||
const maxBudget = userSpendData?.max_budget || null;
|
||||
const displayMaxBudget = maxBudget !== null ? `$${maxBudget} limit` : "No limit";
|
||||
const displayText = `$${spend} / ${displayMaxBudget}`;
|
||||
|
||||
return (
|
||||
<>
|
||||
<Card className="mx-auto mb-4">
|
||||
<Metric>
|
||||
${spend}
|
||||
</Metric>
|
||||
<Title>
|
||||
/ {displayMaxBudget}
|
||||
</Title>
|
||||
</Card>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default ViewUserSpend;
|
||||
|
||||
Loading…
Add table
Reference in a new issue