mirror of
https://github.com/BerriAI/litellm.git
synced 2026-11-06 07:48:06 +00:00
fix(fallback): keep the config-owned 400 for an unset env reference and replace a non-object stored row
This commit is contained in:
parent
d85848667a
commit
fb5bad80ef
2 changed files with 26 additions and 11 deletions
|
|
@ -61,7 +61,7 @@ async def _reload_config_file_ownership(proxy_config: "ProxyConfig") -> None:
|
|||
|
||||
async def _stored_router_settings(prisma_client: PrismaClient) -> Mapping[str, JsonValue]:
|
||||
row: Final = await ConfigRepository(prisma_client, use_writer=True).get_param(ROUTER_SETTINGS_PARAM)
|
||||
if row is None or row.param_value is None:
|
||||
if row is None or not isinstance(row.param_value, Mapping):
|
||||
return {}
|
||||
return _STORED_ROUTER_SETTINGS.validate_python(row.param_value)
|
||||
|
||||
|
|
@ -70,12 +70,10 @@ def _editable_rules(
|
|||
proxy_config: "ProxyConfig", stored_settings: Mapping[str, JsonValue], fallback_key: str
|
||||
) -> list[StoredFallback]:
|
||||
file_settings: Final = proxy_config.router_settings
|
||||
rules: Final = (
|
||||
file_settings.config_value(fallback_key)
|
||||
if file_settings.owned_by_config(fallback_key)
|
||||
else stored_settings.get(fallback_key)
|
||||
)
|
||||
return _STORED_FALLBACKS.validate_python(rules or [])
|
||||
if not file_settings.owned_by_config(fallback_key):
|
||||
return _STORED_FALLBACKS.validate_python(stored_settings.get(fallback_key) or [])
|
||||
file_rules: Final = file_settings.config_value(fallback_key)
|
||||
return _STORED_FALLBACKS.validate_python(file_rules if isinstance(file_rules, list) else [])
|
||||
|
||||
|
||||
async def _write_rules(
|
||||
|
|
|
|||
|
|
@ -134,7 +134,7 @@ PRIMARY_DEPLOYMENT_ID: Final = "team-primary-id"
|
|||
FALLBACK_DEPLOYMENT_ID: Final = "team-fallback-id"
|
||||
|
||||
FallbackRules = list[dict[str, list[str]] | dict[str, object] | str]
|
||||
RouterSettings = dict[str, FallbackRules | None]
|
||||
RouterSettings = dict[str, FallbackRules | str | None]
|
||||
_ROUTER_SETTINGS_JSON: Final = TypeAdapter(dict[str, JsonValue])
|
||||
|
||||
|
||||
|
|
@ -435,13 +435,14 @@ class TestFallbackWritesSeeTheLatestStoredRules:
|
|||
|
||||
assert stored.stored_fallbacks() == [GATEWAY_RULE]
|
||||
|
||||
async def test_a_create_treats_a_null_stored_row_as_empty(self) -> None:
|
||||
@pytest.mark.parametrize("param_value", [None, ["team-primary"], 7])
|
||||
async def test_a_create_replaces_a_stored_row_that_is_not_an_object(self, param_value: JsonValue) -> None:
|
||||
stored: Final = _StoredRouterSettings(None)
|
||||
stored.row = SimpleNamespace(param_name="router_settings", param_value=None)
|
||||
stored.row = SimpleNamespace(param_name="router_settings", param_value=param_value)
|
||||
|
||||
await self._create(FallbackCreateRequest(model="gpt-5.4-mini", fallback_models=["team-fallback"]), stored)
|
||||
|
||||
assert stored.stored_fallbacks() == [GATEWAY_RULE]
|
||||
assert stored.row.param_value == {"fallbacks": [GATEWAY_RULE]}
|
||||
|
||||
|
||||
CONFIG_RULE: Final = {"gpt-5.4-mini": ["team-fallback"]}
|
||||
|
|
@ -539,6 +540,22 @@ class TestFallbackWritesHonourTheConfigFile:
|
|||
assert stored.row is None
|
||||
assert router.fallbacks == [CONFIG_RULE]
|
||||
|
||||
async def test_writes_to_a_config_file_env_reference_that_resolves_to_nothing_are_refused(
|
||||
self, router: Router, monkeypatch: pytest.MonkeyPatch
|
||||
) -> None:
|
||||
monkeypatch.delenv("LITELLM_TEST_UNSET_FALLBACKS", raising=False)
|
||||
stored: Final = _StoredRouterSettings(None, config_file={"fallbacks": "os.environ/LITELLM_TEST_UNSET_FALLBACKS"})
|
||||
|
||||
with pytest.raises(HTTPException) as refused:
|
||||
await self._create(FallbackCreateRequest(model="team-primary", fallback_models=["team-fallback"]), router, stored)
|
||||
with pytest.raises(HTTPException) as not_found:
|
||||
await self._delete("team-primary", router, stored)
|
||||
|
||||
assert refused.value.status_code == 400
|
||||
assert "key 'fallbacks' is set in the config file" in str(refused.value.detail)
|
||||
assert not_found.value.status_code == 404
|
||||
assert stored.row is None
|
||||
|
||||
async def test_a_create_that_restates_one_of_several_config_rules_writes_nothing(self, router: Router) -> None:
|
||||
stored: Final = _StoredRouterSettings(None, config_file={"fallbacks": [CONFIG_RULE, CONFIG_WINDOW_RULE]})
|
||||
request: Final = FallbackCreateRequest(model="gpt-5.4-mini", fallback_models=["team-fallback"])
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue