mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-22 00:31:44 +00:00
fix(proxy): keep a config-owned key's resolved value across a database reload
Applying a database row dropped the runtime layer for every key the row carried, including keys the config file owns. Those runtime entries hold the env-resolved config values, so after a reload a key written as os.environ/<NAME> read back as that literal string. The store now keeps the runtime entry for a key the config owns and clears only the rest. Visible as store_model_in_db silently turning itself off: the reload read the raw reference, coerced it to False, and overwrote the resolved global.
This commit is contained in:
parent
3d2ec85215
commit
c9158fcc12
3 changed files with 33 additions and 4 deletions
|
|
@ -117,12 +117,13 @@ class SettingsStore(MutableMapping[str, JsonValue]):
|
|||
self._deleted_runtime_keys = frozenset()
|
||||
|
||||
def _clear_runtime_keys(self, keys: frozenset[str]) -> None:
|
||||
if not keys:
|
||||
stale: Final = frozenset(key for key in keys if not self.owned_by_config(key))
|
||||
if not stale:
|
||||
return
|
||||
self._runtime_values = MappingProxyType(
|
||||
{key: value for key, value in self._runtime_values.items() if key not in keys}
|
||||
{key: value for key, value in self._runtime_values.items() if key not in stale}
|
||||
)
|
||||
self._deleted_runtime_keys = self._deleted_runtime_keys - keys
|
||||
self._deleted_runtime_keys = self._deleted_runtime_keys - stale
|
||||
|
||||
def _keys(self) -> tuple[str, ...]:
|
||||
return tuple(
|
||||
|
|
|
|||
|
|
@ -86,7 +86,6 @@ def test_settings_store_keeps_unaffected_runtime_values_on_a_db_row_refresh() ->
|
|||
def test_settings_store_keeps_a_config_owned_key_when_a_db_row_disagrees() -> None:
|
||||
store: Final = SettingsStore("general_settings")
|
||||
store.load_yaml({"changed": "config"})
|
||||
store.apply_runtime_values({"changed": "resolved-config"})
|
||||
|
||||
store.apply_db_row("general_settings", {"changed": "database"})
|
||||
|
||||
|
|
@ -94,6 +93,17 @@ def test_settings_store_keeps_a_config_owned_key_when_a_db_row_disagrees() -> No
|
|||
assert store.source("changed") == "config"
|
||||
|
||||
|
||||
def test_settings_store_keeps_the_resolved_value_of_a_config_owned_key_across_a_db_row() -> None:
|
||||
store: Final = SettingsStore("general_settings")
|
||||
store.load_yaml({"changed": "os.environ/SETTING"})
|
||||
store.apply_runtime_values({"changed": "resolved-config"})
|
||||
|
||||
store.apply_db_row("general_settings", {"changed": "database"})
|
||||
|
||||
assert store["changed"] == "resolved-config"
|
||||
assert store.source("changed") == "config"
|
||||
|
||||
|
||||
def test_settings_store_removes_only_runtime_values_affected_by_a_cleared_db_row() -> None:
|
||||
store: Final = SettingsStore("general_settings")
|
||||
store.load_yaml({"template": "os.environ/SETTING"})
|
||||
|
|
|
|||
|
|
@ -3381,6 +3381,24 @@ async def test_db_reload_finishes_when_the_config_owns_a_setting_the_db_also_set
|
|||
assert proxy_config.settings["user_api_key_cache_max_size"] == config_cache_size
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_db_reload_keeps_the_resolved_value_of_a_config_owned_env_reference(monkeypatch):
|
||||
from litellm.proxy import proxy_server as proxy_server_module
|
||||
from litellm.proxy.proxy_server import ProxyConfig
|
||||
|
||||
monkeypatch.setattr(proxy_server_module, "user_api_key_cache", MagicMock(), raising=False)
|
||||
monkeypatch.setattr(proxy_server_module, "store_model_in_db", True, raising=False)
|
||||
proxy_config: Final = ProxyConfig()
|
||||
proxy_config.settings.load_yaml({"store_model_in_db": "os.environ/PROOF_STORE_FLAG"})
|
||||
proxy_config.settings.apply_runtime_values({"store_model_in_db": True})
|
||||
monkeypatch.setattr(proxy_server_module, "general_settings", proxy_config.settings, raising=False)
|
||||
|
||||
await proxy_config._update_general_settings({"store_model_in_db": True})
|
||||
|
||||
assert proxy_config.settings["store_model_in_db"] is True
|
||||
assert proxy_server_module.store_model_in_db is True
|
||||
|
||||
|
||||
def test_max_ui_session_budget_default_is_one_dollar():
|
||||
"""LIT-4662: the dashboard session budget default is a product decision; the
|
||||
old 0.25 default locked admins out of auto router Test Connection and the
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue