From b733275870c36d7068e89dd68db112aadb0d658a Mon Sep 17 00:00:00 2001 From: mrinal Date: Wed, 28 Oct 2026 18:51:52 +0000 Subject: [PATCH] refactor(daily-activity): fold guardrail breakdown in a worker thread and drop docstrings Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> --- .../management_endpoints/common_daily_activity.py | 10 ++++++---- .../spend/test_daily_activity_aggregated_breakdowns.py | 3 --- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/litellm/proxy/management_endpoints/common_daily_activity.py b/litellm/proxy/management_endpoints/common_daily_activity.py index 74d37093a87..0f159363d15 100644 --- a/litellm/proxy/management_endpoints/common_daily_activity.py +++ b/litellm/proxy/management_endpoints/common_daily_activity.py @@ -1042,7 +1042,6 @@ def _day_with_guardrails(day: DailySpendData, rows: Sequence[GuardrailSpendRow]) def _with_guardrail_breakdown( results: Sequence[DailySpendData], rows: Sequence[GuardrailSpendRow] ) -> tuple[DailySpendData, ...]: - """API keys outside the top api_key_limit stay in each guardrail's spend but not in its api_key_breakdown.""" rows_by_date: Final = MappingProxyType( {day: tuple(group) for day, group in groupby(sorted(rows, key=lambda row: row.date), key=lambda row: row.date)} ) @@ -1112,10 +1111,13 @@ async def get_daily_activity_aggregated( api_key_metadata=entity_key_metadata, entity_metadata_field=entity_metadata_field, ) - return SpendAnalyticsPaginatedResponse( - results=list(_with_guardrail_breakdown(aggregated["results"], guardrail_rows)) + results: Final = ( + list(await asyncio.to_thread(_with_guardrail_breakdown, aggregated["results"], guardrail_rows)) if guardrail_rows - else aggregated["results"], + else aggregated["results"] + ) + return SpendAnalyticsPaginatedResponse( + results=results, metadata=DailySpendMetadata( total_spend=aggregated["totals"].spend, total_flat_cost=aggregated["totals"].flat_cost, diff --git a/tests/integration/spend/test_daily_activity_aggregated_breakdowns.py b/tests/integration/spend/test_daily_activity_aggregated_breakdowns.py index 1cdf745f1f6..90ade6623b8 100644 --- a/tests/integration/spend/test_daily_activity_aggregated_breakdowns.py +++ b/tests/integration/spend/test_daily_activity_aggregated_breakdowns.py @@ -275,9 +275,6 @@ def _day_breakdown(gateway: Gateway, day: str, **params: str) -> dict[str, JsonV @pytest.mark.asyncio async def test_get_daily_activity_aggregated_breaks_down_guardrail_spend(gateway: Gateway) -> None: - """Guardrail cost per guardrail and key follows the request's user, model and api_key_limit scope. - orphan-key has guardrail cost but no spend row on the day, so no user scope reaches it. Model spend - keeps the guardrail cost it already carries.""" day: Final = _unique_day() _seed( day,