From f30bfcf36a6621e4b31cbd21042ab22fd07ea8b5 Mon Sep 17 00:00:00 2001 From: user <70670632+stuxf@users.noreply.github.com> Date: Thu, 30 Apr 2026 20:36:14 -0700 Subject: [PATCH] add budget reservation disable flag --- litellm/proxy/auth/user_api_key_auth.py | 6 +++- .../proxy/auth/test_user_api_key_auth.py | 29 +++++++++++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/litellm/proxy/auth/user_api_key_auth.py b/litellm/proxy/auth/user_api_key_auth.py index 2495d33a5c..ea7bad2bf4 100644 --- a/litellm/proxy/auth/user_api_key_auth.py +++ b/litellm/proxy/auth/user_api_key_auth.py @@ -1909,7 +1909,7 @@ async def _reserve_budget_after_common_checks( end_user_object: Optional[LiteLLM_EndUserTable] = None, ) -> None: user_api_key_auth_obj.budget_reservation = None - if skip_budget_checks: + if skip_budget_checks or _is_budget_reservation_disabled(): return from litellm.proxy.spend_tracking.budget_reservation import ( @@ -1931,6 +1931,10 @@ async def _reserve_budget_after_common_checks( ) +def _is_budget_reservation_disabled() -> bool: + return get_secret_bool("LITELLM_DISABLE_BUDGET_RESERVATION", False) is True + + def _should_skip_budget_checks( request_data: dict, route: str, diff --git a/tests/test_litellm/proxy/auth/test_user_api_key_auth.py b/tests/test_litellm/proxy/auth/test_user_api_key_auth.py index 83e4788fa1..8489a7b0f6 100644 --- a/tests/test_litellm/proxy/auth/test_user_api_key_auth.py +++ b/tests/test_litellm/proxy/auth/test_user_api_key_auth.py @@ -77,6 +77,35 @@ async def test_should_clear_stale_budget_reservation_when_budget_checks_skip(): assert user_api_key_auth_obj.budget_reservation is None +@pytest.mark.asyncio +async def test_should_skip_budget_reservation_when_disabled(): + user_api_key_auth_obj = UserAPIKeyAuth( + token="test_token", + spend=0.0, + max_budget=1.0, + budget_reservation={ + "reserved_cost": 0.5, + "entries": [{"counter_key": "spend:key:test_token"}], + }, + ) + + with patch.dict(os.environ, {"LITELLM_DISABLE_BUDGET_RESERVATION": "true"}): + await _reserve_budget_after_common_checks( + user_api_key_auth_obj=user_api_key_auth_obj, + request_data={"model": "gpt-4"}, + route="/v1/chat/completions", + llm_router=None, + team_object=None, + user_object=None, + prisma_client=None, + user_api_key_cache=DualCache(), + proxy_logging_obj=MagicMock(), + skip_budget_checks=False, + ) + + assert user_api_key_auth_obj.budget_reservation is None + + @pytest.mark.asyncio async def test_should_not_reuse_cached_key_object_for_request_state(): key_cache = DualCache()