Add /broker/usage (spend vs balance) + fix broker to use member balance

This commit is contained in:
inference-bot committed 2026-09-14 10:46:47 -06:00
1 parent 71d63955b3
commit a46c016817
1 file changed
+34 -1
+34 -1
View File
@@ -718,7 +718,8 @@ async def broker_create_api_key(email: str, name: str) -> dict:
if not name or not re.fullmatch(r"[A-Za-z0-9._-]{1,64}", name):
raise HTTPException(400, "Invalid key name (1-64 chars, alphanumeric/._-)")
team_id = await litellm_get_or_create_team(email, MEMBER_BUDGET)
balance = get_member_balance(email)
team_id = await litellm_get_or_create_team(email, balance)
alias = _api_key_alias(email, name)
async with httpx.AsyncClient() as client:
r = await client.post(
@@ -1140,6 +1141,38 @@ async def broker_revoke(name: str, request: Request):
return {"status": "revoked", "name": name}
async def broker_get_usage(email: str) -> dict:
"""Return the member's spend vs. balance, from their team.
LiteLLM's team object exposes `spend` and `max_budget` directly, so we read
the member's team and return {balance, spend, remaining}. This is the
read-only primitive the member dashboard uses (no master key on the client).
"""
team_id = await litellm_get_or_create_team(email, get_member_balance(email))
async with httpx.AsyncClient() as client:
r = await client.get(
f"{LITELLM_BASE}/team/list",
headers={"Authorization": f"Bearer {LITELLM_MASTER_KEY}"},
)
r.raise_for_status()
for t in r.json():
if t.get("team_id") == team_id:
balance = float(t.get("max_budget") or get_member_balance(email))
spend = float(t.get("spend") or 0.0)
return {
"balance": balance,
"spend": spend,
"remaining": max(balance - spend, 0.0),
}
return {"balance": get_member_balance(email), "spend": 0.0, "remaining": get_member_balance(email)}
@app.get("/broker/usage")
async def broker_usage(request: Request):
email = _verify_broker_secret(request)
return await broker_get_usage(email)
async def reconcile_memberships() -> dict:
"""Reconcile the portal against the live Open Collective member list.