mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-10 22:41:41 +00:00
docs(key budgets): state why a swallowed lookup reports unlimited, not unknown
Several of the helpers this reads entities through swallow a read error and hand back an absence instead of raising. Enforcement calls those same helpers and acts on that same absence, so a scope reported as unlimited is one no check will apply on the request the row describes. _Unavailable is for the helpers that do raise, whose failure leaves a budget that would still gate the request, and those report unknown. Pins both halves: a tag whose fetch failed open, and a team whose lookup raised.
This commit is contained in:
parent
6a6e5877d9
commit
5bbf1452b3
2 changed files with 34 additions and 1 deletions
|
|
@ -7,7 +7,11 @@ live spend, and the operator the enforcing check compares with.
|
|||
|
||||
The limit and counter for each scope come from the same helpers enforcement uses, so
|
||||
the two cannot disagree about which budget applies or which counter it is measured
|
||||
against.
|
||||
against. That holds through failure too: several of those helpers swallow a read
|
||||
error and hand back an absence rather than raising, and since enforcement acts on
|
||||
that same absence, a scope this reports as unlimited is one no check will apply on
|
||||
the request it describes. ``_Unavailable`` is for the helpers that do raise, whose
|
||||
failures leave a budget that would still be enforced, and those become ``unknown``.
|
||||
"""
|
||||
|
||||
import asyncio
|
||||
|
|
|
|||
|
|
@ -17326,3 +17326,32 @@ async def test_key_budgets_route_shows_the_proxy_numbers_only_to_a_proxy_wide_re
|
|||
|
||||
assert response.status_code == 200
|
||||
assert resolver.await_args.kwargs["deps"].proxy_spend_visible is expected
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_key_budgets_report_a_tag_its_own_fetch_fails_open_on_the_way_the_request_will_see_it():
|
||||
"""
|
||||
`_fetch_uncached_tags` swallows a failed tag fetch into "no budget objects" so auth never breaks
|
||||
on it, and the enforcing check reads that same empty result. Reporting the tag as unknown would
|
||||
name a limit that will not be applied to the request this row describes.
|
||||
"""
|
||||
world = _fully_populated_world(tags={})
|
||||
with _budgets_world(**world):
|
||||
budgets = await resolve_key_budgets(valid_token=_budgets_token(), end_user_id=None, deps=_budgets_deps())
|
||||
|
||||
entry = next(e for e in budgets if e.scope == "tag")
|
||||
assert (entry.max_budget, entry.status) == (None, "unlimited")
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_key_budgets_report_a_scope_whose_helper_raises_as_unknown_rather_than_unlimited():
|
||||
"""`get_team_object` raises rather than swallowing, so a request would still be gated on the team."""
|
||||
|
||||
async def _explode(**kwargs):
|
||||
raise RuntimeError("team lookup is down")
|
||||
|
||||
with _budgets_world(**_fully_populated_world()), patch(f"{_BUDGETS_RESOLVER}.get_team_object", _explode):
|
||||
budgets = await resolve_key_budgets(valid_token=_budgets_token(), end_user_id=None, deps=_budgets_deps())
|
||||
|
||||
entry = next(e for e in budgets if e.scope == "team")
|
||||
assert (entry.max_budget, entry.spend, entry.status) == (None, None, "unknown")
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue