mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-22 00:31:44 +00:00
fix(proxy): treat non-positive project max_budget as unbudgeted
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
parent
bde5593523
commit
7e5b3b49d4
2 changed files with 24 additions and 1 deletions
|
|
@ -5612,7 +5612,7 @@ async def _project_max_budget_check(
|
|||
if project_object.litellm_budget_table is not None:
|
||||
max_budget = project_object.litellm_budget_table.max_budget
|
||||
|
||||
if max_budget is None or not math.isfinite(max_budget):
|
||||
if max_budget is None or max_budget <= 0 or not math.isfinite(max_budget):
|
||||
return
|
||||
|
||||
from litellm.proxy.proxy_server import get_current_spend
|
||||
|
|
|
|||
|
|
@ -7378,6 +7378,29 @@ async def test_project_max_budget_check_reads_live_spend_counter(counter_spend,
|
|||
assert proxy_logging_obj.budget_alerts.await_args.kwargs["type"] == "project_budget"
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.parametrize("max_budget", [0.0, -1.0])
|
||||
async def test_project_max_budget_check_treats_non_positive_budget_as_unbudgeted(max_budget):
|
||||
from litellm.caching.dual_cache import DualCache
|
||||
from litellm.proxy.auth.auth_checks import _project_max_budget_check
|
||||
|
||||
real_spend_counter_cache = DualCache()
|
||||
real_spend_counter_cache.in_memory_cache.set_cache(key="spend:project:p-budget", value=12.5)
|
||||
proxy_logging_obj = MagicMock()
|
||||
proxy_logging_obj.budget_alerts = AsyncMock()
|
||||
|
||||
with patch( # test-quality-ok: injects a real DualCache for the module global, not a behavior mock
|
||||
"litellm.proxy.proxy_server.spend_counter_cache", real_spend_counter_cache
|
||||
):
|
||||
await _project_max_budget_check(
|
||||
project_object=_project_with_budget(spend=12.5, max_budget=max_budget),
|
||||
valid_token=UserAPIKeyAuth(api_key="hashed-key", project_id="p-budget"),
|
||||
proxy_logging_obj=proxy_logging_obj,
|
||||
)
|
||||
|
||||
proxy_logging_obj.budget_alerts.assert_not_awaited()
|
||||
|
||||
|
||||
def test_is_user_proxy_admin_rejects_view_only_admin():
|
||||
"""This predicate skips `non_proxy_admin_allowed_routes_check` entirely, so an
|
||||
Admin Viewer answering True here would gain every write route. Read parity for
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue