mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-11 22:51:28 +00:00
feat(logging): add user and team level spend and budget to StandardLoggingPayload metadata (#33459)
* feat(logging): add user and team level spend and budget to StandardLoggingPayload metadata * fix(logging): include user and team budget fields in dummy standard logging payload
This commit is contained in:
parent
db800152c0
commit
899ddef219
5 changed files with 92 additions and 0 deletions
|
|
@ -113,6 +113,10 @@ class PagerDutyAlerting(SlackAlerting):
|
|||
user_api_key_spend=_meta.get("user_api_key_spend"),
|
||||
user_api_key_max_budget=_meta.get("user_api_key_max_budget"),
|
||||
user_api_key_budget_reset_at=_meta.get("user_api_key_budget_reset_at"),
|
||||
user_api_key_user_spend=_meta.get("user_api_key_user_spend"),
|
||||
user_api_key_user_max_budget=_meta.get("user_api_key_user_max_budget"),
|
||||
user_api_key_team_spend=_meta.get("user_api_key_team_spend"),
|
||||
user_api_key_team_max_budget=_meta.get("user_api_key_team_max_budget"),
|
||||
user_api_key_org_id=_meta.get("user_api_key_org_id"),
|
||||
user_api_key_org_alias=_meta.get("user_api_key_org_alias"),
|
||||
user_api_key_team_id=_meta.get("user_api_key_team_id"),
|
||||
|
|
@ -196,6 +200,10 @@ class PagerDutyAlerting(SlackAlerting):
|
|||
if user_api_key_dict.budget_reset_at
|
||||
else None
|
||||
),
|
||||
user_api_key_user_spend=user_api_key_dict.user_spend,
|
||||
user_api_key_user_max_budget=user_api_key_dict.user_max_budget,
|
||||
user_api_key_team_spend=user_api_key_dict.team_spend,
|
||||
user_api_key_team_max_budget=user_api_key_dict.team_max_budget,
|
||||
user_api_key_org_id=user_api_key_dict.org_id,
|
||||
user_api_key_org_alias=user_api_key_dict.organization_alias,
|
||||
user_api_key_team_id=user_api_key_dict.team_id,
|
||||
|
|
|
|||
|
|
@ -4597,6 +4597,10 @@ class StandardLoggingPayloadSetup:
|
|||
user_api_key_spend=None,
|
||||
user_api_key_max_budget=None,
|
||||
user_api_key_budget_reset_at=None,
|
||||
user_api_key_user_spend=None,
|
||||
user_api_key_user_max_budget=None,
|
||||
user_api_key_team_spend=None,
|
||||
user_api_key_team_max_budget=None,
|
||||
user_api_key_team_id=None,
|
||||
user_api_key_org_id=None,
|
||||
user_api_key_org_alias=None,
|
||||
|
|
@ -5428,6 +5432,10 @@ def get_standard_logging_metadata(
|
|||
user_api_key_spend=None,
|
||||
user_api_key_max_budget=None,
|
||||
user_api_key_budget_reset_at=None,
|
||||
user_api_key_user_spend=None,
|
||||
user_api_key_user_max_budget=None,
|
||||
user_api_key_team_spend=None,
|
||||
user_api_key_team_max_budget=None,
|
||||
user_api_key_team_id=None,
|
||||
user_api_key_org_id=None,
|
||||
user_api_key_org_alias=None,
|
||||
|
|
@ -5527,6 +5535,10 @@ def create_dummy_standard_logging_payload() -> StandardLoggingPayload:
|
|||
user_api_key_team_id=str("test_team"),
|
||||
user_api_key_user_id=str("test_user"),
|
||||
user_api_key_team_alias=str("test_team_alias"),
|
||||
user_api_key_user_spend=None,
|
||||
user_api_key_user_max_budget=None,
|
||||
user_api_key_team_spend=None,
|
||||
user_api_key_team_max_budget=None,
|
||||
user_api_key_org_id=None,
|
||||
spend_logs_metadata=None,
|
||||
requester_ip_address=str("127.0.0.1"),
|
||||
|
|
|
|||
|
|
@ -949,6 +949,10 @@ class LiteLLMProxyRequestSetup:
|
|||
user_api_key_alias=user_api_key_dict.key_alias,
|
||||
user_api_key_spend=user_api_key_dict.spend,
|
||||
user_api_key_max_budget=user_api_key_dict.max_budget,
|
||||
user_api_key_user_spend=user_api_key_dict.user_spend,
|
||||
user_api_key_user_max_budget=user_api_key_dict.user_max_budget,
|
||||
user_api_key_team_spend=user_api_key_dict.team_spend,
|
||||
user_api_key_team_max_budget=user_api_key_dict.team_max_budget,
|
||||
user_api_key_team_id=user_api_key_dict.team_id,
|
||||
user_api_key_project_id=user_api_key_dict.project_id,
|
||||
user_api_key_project_alias=user_api_key_dict.project_alias,
|
||||
|
|
|
|||
|
|
@ -2475,6 +2475,10 @@ class StandardLoggingUserAPIKeyMetadata(TypedDict):
|
|||
user_api_key_spend: Optional[float]
|
||||
user_api_key_max_budget: Optional[float]
|
||||
user_api_key_budget_reset_at: Optional[str]
|
||||
user_api_key_user_spend: Optional[float]
|
||||
user_api_key_user_max_budget: Optional[float]
|
||||
user_api_key_team_spend: Optional[float]
|
||||
user_api_key_team_max_budget: Optional[float]
|
||||
user_api_key_org_id: Optional[str]
|
||||
user_api_key_org_alias: Optional[str]
|
||||
user_api_key_team_id: Optional[str]
|
||||
|
|
|
|||
|
|
@ -2688,6 +2688,70 @@ def test_get_sanitized_user_information_from_key_includes_guardrails_metadata():
|
|||
assert result["user_api_key_auth_metadata"]["other_field"] == "value"
|
||||
|
||||
|
||||
def test_user_and_team_spend_and_budget_flow_to_standard_logging_metadata():
|
||||
"""
|
||||
Full flow: UserAPIKeyAuth -> get_sanitized_user_information_from_key ->
|
||||
get_standard_logging_metadata. User-level and team-level spend + max budget
|
||||
must reach the StandardLoggingPayload metadata that custom loggers receive,
|
||||
alongside the key-level values
|
||||
"""
|
||||
from litellm.litellm_core_utils.litellm_logging import StandardLoggingPayloadSetup
|
||||
|
||||
user_api_key_dict = UserAPIKeyAuth(
|
||||
api_key="test-key-hash",
|
||||
spend=1.5,
|
||||
max_budget=10.0,
|
||||
user_id="test-user",
|
||||
user_spend=25.5,
|
||||
user_max_budget=100.0,
|
||||
team_id="test-team",
|
||||
team_spend=250.75,
|
||||
team_max_budget=1000.0,
|
||||
)
|
||||
|
||||
sanitized = LiteLLMProxyRequestSetup.get_sanitized_user_information_from_key(
|
||||
user_api_key_dict=user_api_key_dict
|
||||
)
|
||||
|
||||
assert sanitized["user_api_key_spend"] == 1.5
|
||||
assert sanitized["user_api_key_max_budget"] == 10.0
|
||||
assert sanitized["user_api_key_user_spend"] == 25.5
|
||||
assert sanitized["user_api_key_user_max_budget"] == 100.0
|
||||
assert sanitized["user_api_key_team_spend"] == 250.75
|
||||
assert sanitized["user_api_key_team_max_budget"] == 1000.0
|
||||
|
||||
logging_metadata = StandardLoggingPayloadSetup.get_standard_logging_metadata(
|
||||
dict(sanitized)
|
||||
)
|
||||
|
||||
assert logging_metadata["user_api_key_user_spend"] == 25.5
|
||||
assert logging_metadata["user_api_key_user_max_budget"] == 100.0
|
||||
assert logging_metadata["user_api_key_team_spend"] == 250.75
|
||||
assert logging_metadata["user_api_key_team_max_budget"] == 1000.0
|
||||
|
||||
|
||||
def test_user_and_team_spend_and_budget_default_to_none_in_standard_logging_metadata():
|
||||
"""
|
||||
Keys with no user or team level budgets report None for the new fields in the
|
||||
StandardLoggingPayload metadata instead of raising
|
||||
"""
|
||||
from litellm.litellm_core_utils.litellm_logging import StandardLoggingPayloadSetup
|
||||
|
||||
user_api_key_dict = UserAPIKeyAuth(api_key="test-key-hash")
|
||||
|
||||
sanitized = LiteLLMProxyRequestSetup.get_sanitized_user_information_from_key(
|
||||
user_api_key_dict=user_api_key_dict
|
||||
)
|
||||
logging_metadata = StandardLoggingPayloadSetup.get_standard_logging_metadata(
|
||||
dict(sanitized)
|
||||
)
|
||||
|
||||
assert logging_metadata["user_api_key_user_spend"] is None
|
||||
assert logging_metadata["user_api_key_user_max_budget"] is None
|
||||
assert logging_metadata["user_api_key_team_spend"] is None
|
||||
assert logging_metadata["user_api_key_team_max_budget"] is None
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_team_guardrails_append_to_key_guardrails():
|
||||
"""
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue