mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-07 02:59:05 +00:00
refactor(key management): tighten the key budgets response types
entity_type was declared str, so the generated client saw a bare string even though the resolver already carried a Litellm_EntityType and only called .value at the boundary. Declaring the enum keeps the wire format identical and lets a caller match a BudgetExceededError's entity against a row without comparing loose strings. key is populated on every 200, since a request that resolves no key 404s before the response is built, so declaring it optional understated the contract.
This commit is contained in:
parent
83cbee007a
commit
4b8368a27d
3 changed files with 22 additions and 15 deletions
|
|
@ -390,7 +390,7 @@ def _to_entry(plan: _PlannedBudget, spend: float | None) -> KeyBudgetEntry:
|
|||
)
|
||||
return KeyBudgetEntry(
|
||||
scope=plan.scope,
|
||||
entity_type=_ENTITY_TYPE_BY_SCOPE[plan.scope].value,
|
||||
entity_type=_ENTITY_TYPE_BY_SCOPE[plan.scope],
|
||||
entity_id=plan.entity_id,
|
||||
entity_label=plan.entity_label,
|
||||
enforcement=plan.enforcement,
|
||||
|
|
|
|||
|
|
@ -3753,6 +3753,15 @@ async def info_key_fn(
|
|||
raise handle_exception_on_proxy(e)
|
||||
|
||||
|
||||
def _key_not_found_error() -> ProxyException:
|
||||
return ProxyException(
|
||||
message="Key not found in database",
|
||||
type=ProxyErrorTypes.not_found_error,
|
||||
param="key",
|
||||
code=status.HTTP_404_NOT_FOUND,
|
||||
)
|
||||
|
||||
|
||||
@router.get(
|
||||
"/key/{key_id}/budgets",
|
||||
tags=("key management",),
|
||||
|
|
@ -3798,8 +3807,8 @@ async def key_budgets_fn(
|
|||
- budgets: list - One entry per applicable budget
|
||||
- scope: str - `proxy`, `key`, `key_window`, `key_model`, `team`, `team_window`,
|
||||
`team_member`, `user`, `organization`, `project`, `tag`, `end_user` or `end_user_model`
|
||||
- entity_type: str - The `Litellm_EntityType` a `BudgetExceededError` from this scope
|
||||
carries, so a denial message maps back to a row here
|
||||
- entity_type: Litellm_EntityType - The entity a `BudgetExceededError` from this scope
|
||||
names, so a denial message maps back to a row here
|
||||
- entity_id / entity_label: str | None - Which entity is limited, and its human-facing alias
|
||||
- enforcement: str - `hard` blocks the request, `soft` only raises an alert
|
||||
- max_budget: float | None - The limit in effect. `null` means this scope applies to the key
|
||||
|
|
@ -3839,17 +3848,13 @@ async def key_budgets_fn(
|
|||
)
|
||||
|
||||
key: Final = key_id or user_api_key_dict.api_key
|
||||
hashed_key: Final = _hash_token_if_needed(token=key) if key is not None else None
|
||||
key_info: Final = (
|
||||
await VerificationTokenRepository(prisma_client).find_by_id(hashed_key) if hashed_key is not None else None
|
||||
)
|
||||
if key is None:
|
||||
raise _key_not_found_error()
|
||||
|
||||
hashed_key: Final = _hash_token_if_needed(token=key)
|
||||
key_info: Final = await VerificationTokenRepository(prisma_client).find_by_id(hashed_key)
|
||||
if key_info is None:
|
||||
raise ProxyException(
|
||||
message="Key not found in database",
|
||||
type=ProxyErrorTypes.not_found_error,
|
||||
param="key",
|
||||
code=status.HTTP_404_NOT_FOUND,
|
||||
)
|
||||
raise _key_not_found_error()
|
||||
|
||||
if (
|
||||
await _can_user_query_key_info(
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@ from typing import Any, Final, Literal
|
|||
|
||||
from pydantic import BaseModel, ConfigDict, model_validator
|
||||
|
||||
from litellm.proxy._types import Litellm_EntityType
|
||||
|
||||
|
||||
class BulkUpdateKeyRequestItem(BaseModel):
|
||||
"""Individual key update request item"""
|
||||
|
|
@ -135,7 +137,7 @@ class KeyBudgetEntry(BaseModel):
|
|||
"""One budget that can gate requests made with a key, with its live spend."""
|
||||
|
||||
scope: BudgetScope
|
||||
entity_type: str
|
||||
entity_type: Litellm_EntityType
|
||||
entity_id: str | None = None
|
||||
entity_label: str | None = None
|
||||
enforcement: BudgetEnforcement
|
||||
|
|
@ -154,5 +156,5 @@ class KeyBudgetEntry(BaseModel):
|
|||
class KeyBudgetsResponse(BaseModel):
|
||||
"""Every budget that applies to one key, including the ones left unconfigured."""
|
||||
|
||||
key: str | None = None
|
||||
key: str
|
||||
budgets: tuple[KeyBudgetEntry, ...]
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue