Add /admin/model-usage endpoint (co-op per-model spend/tokens/requests)
This commit is contained in:
1 parent
e92e29bac0
commit
810b878014
1 file changed
+53
+53
@@ -1318,6 +1318,59 @@ async def admin_overview(request: Request):
|
||||
}
|
||||
|
||||
|
||||
@app.get("/admin/model-usage")
|
||||
@limiter.limit("30/minute")
|
||||
async def admin_model_usage(request: Request):
|
||||
"""Co-op-wide per-model usage from LiteLLM spend logs.
|
||||
|
||||
Authenticated by the X-Admin-Token header. Aggregates every spend-log row
|
||||
(across ALL members) by model: total spend, tokens, and request count,
|
||||
sorted by spend descending. No per-member breakdown — this is co-op-level
|
||||
so admins can see which models the membership actually uses.
|
||||
"""
|
||||
_verify_admin_token(request)
|
||||
|
||||
models = {}
|
||||
total_spend = 0.0
|
||||
total_tokens = 0
|
||||
total_requests = 0
|
||||
try:
|
||||
async with httpx.AsyncClient(timeout=30.0) as client:
|
||||
r = await client.get(
|
||||
f"{LITELLM_BASE}/spend/logs",
|
||||
headers={"Authorization": f"Bearer {LITELLM_MASTER_KEY}"},
|
||||
)
|
||||
r.raise_for_status()
|
||||
rows = r.json()
|
||||
if isinstance(rows, dict):
|
||||
rows = rows.get("data", rows.get("logs", []))
|
||||
for row in rows if isinstance(rows, list) else []:
|
||||
model = row.get("model") or row.get("model_group") or "unknown"
|
||||
m = models.setdefault(model, {"spend": 0.0, "tokens": 0, "requests": 0})
|
||||
m["spend"] += float(row.get("spend") or 0.0)
|
||||
m["tokens"] += int(row.get("total_tokens") or 0)
|
||||
m["requests"] += 1
|
||||
total_spend += float(row.get("spend") or 0.0)
|
||||
total_tokens += int(row.get("total_tokens") or 0)
|
||||
total_requests += 1
|
||||
except Exception as e:
|
||||
logger.warning("admin model-usage: spend/logs fetch failed: %s", e)
|
||||
|
||||
model_list = [
|
||||
{"model": name, **stats}
|
||||
for name, stats in sorted(models.items(), key=lambda kv: kv[1]["spend"], reverse=True)
|
||||
]
|
||||
|
||||
return {
|
||||
"models": model_list,
|
||||
"totals": {
|
||||
"total_spend": total_spend,
|
||||
"total_tokens": total_tokens,
|
||||
"total_requests": total_requests,
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
# --- Broker HTTP endpoints (called by the member dashboard) ---
|
||||
# The dashboard is Cloudron-SSO-gated; it authenticates the member and passes
|
||||
# their email with a shared secret. The portal trusts the email only because it
|
||||
|
||||
Reference in new issue
Block a user