Skip to content

Commit 2b2d6d7

Browse files
committed
fix(proxy): apply DB-persisted safe litellm settings on every worker's config reload
Peer workers previously kept their startup value for block_requests_for_models_without_pricing until a restart, so a toggle from the UI only took effect on the worker that served the request.
1 parent eb8d402 commit 2b2d6d7

2 files changed

Lines changed: 39 additions & 0 deletions

File tree

litellm/proxy/proxy_server.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6823,6 +6823,19 @@ async def _init_non_llm_objects_in_db(self, prisma_client: PrismaClient):
68236823

68246824
if self._should_load_db_object(object_type="config_overrides"):
68256825
await self._init_hashicorp_vault_config_override(prisma_client=prisma_client)
6826+
await self._apply_safe_litellm_settings_overrides_from_db(prisma_client=prisma_client)
6827+
6828+
async def _apply_safe_litellm_settings_overrides_from_db(self, prisma_client: PrismaClient) -> None:
6829+
config_record: Final = await get_config_param(prisma_client, "litellm_settings")
6830+
if config_record is None or config_record.param_value is None:
6831+
return
6832+
raw_settings: Final = config_record.param_value
6833+
litellm_settings: Final = json.loads(raw_settings) if isinstance(raw_settings, str) else raw_settings
6834+
if not isinstance(litellm_settings, dict):
6835+
return
6836+
for key, value in litellm_settings.items():
6837+
if key in LITELLM_SETTINGS_SAFE_DB_OVERRIDES:
6838+
setattr(litellm, key, value)
68266839

68276840
async def _init_semantic_filter_settings_in_db(self, prisma_client: PrismaClient):
68286841
"""

tests/test_litellm/proxy/management_endpoints/test_cost_tracking_settings.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -740,6 +740,32 @@ def test_peer_workers_pick_up_persisted_flag_on_config_reload(self):
740740

741741
assert litellm.block_requests_for_models_without_pricing is True
742742

743+
@pytest.mark.asyncio
744+
async def test_periodic_db_sync_applies_flag_to_peer_worker(self):
745+
"""The ~10s reconcile loop runs _init_non_llm_objects_in_db on every worker; it must apply
746+
the persisted flag so peers converge without a restart."""
747+
from types import SimpleNamespace
748+
749+
from litellm.proxy.proxy_server import ProxyConfig
750+
751+
config_record = SimpleNamespace(
752+
param_value={"block_requests_for_models_without_pricing": True, "unsafe_key": "x"}
753+
)
754+
with (
755+
patch.object(litellm, "block_requests_for_models_without_pricing", False),
756+
patch.object(
757+
ProxyConfig,
758+
"_should_load_db_object",
759+
side_effect=lambda object_type: object_type == "config_overrides",
760+
),
761+
patch.object(ProxyConfig, "_init_hashicorp_vault_config_override", AsyncMock()),
762+
patch("litellm.proxy.proxy_server.get_config_param", AsyncMock(return_value=config_record)),
763+
):
764+
await ProxyConfig()._init_non_llm_objects_in_db(prisma_client=MagicMock())
765+
766+
assert litellm.block_requests_for_models_without_pricing is True
767+
assert not hasattr(litellm, "unsafe_key")
768+
743769
@pytest.mark.asyncio
744770
async def test_patch_requires_store_model_in_db(self):
745771
with (

0 commit comments

Comments
 (0)