mirror of
https://github.com/BerriAI/litellm.git
synced 2026-11-11 08:38:24 +00:00
fix(credentials): preserve stored info when patching credentials (#49919)
* fix(credentials): preserve stored info when patching credentials Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * test(credentials): type patch test parameters Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> --------- Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
parent
d1e4b50d6a
commit
de7bb21887
3 changed files with 21 additions and 4 deletions
|
|
@ -920,8 +920,6 @@ def update_db_credential(
|
|||
# update model info
|
||||
if encrypted_credential.credential_info:
|
||||
"""Update credential info"""
|
||||
if "credential_info" not in merged_credential.credential_info:
|
||||
merged_credential.credential_info = {}
|
||||
merged_credential.credential_info.update(encrypted_credential.credential_info)
|
||||
|
||||
return merged_credential
|
||||
|
|
|
|||
|
|
@ -122,6 +122,9 @@ def test_patch_rename_is_rejected_and_model_keeps_working(gateway: Gateway) -> N
|
|||
"PATCH", f"/credentials/{name}", {"credential_name": name, "credential_info": {"description": "y"}}
|
||||
)
|
||||
assert same_name.status_code == 200, same_name.text
|
||||
assert read_rows(
|
||||
'SELECT credential_info FROM "LiteLLM_CredentialsTable" WHERE credential_name = %s', (name,)
|
||||
) == [{"credential_info": {"custom_llm_provider": "openai", "description": "y"}}]
|
||||
assert _served_credential(gateway, name)["credential_info"] == {
|
||||
"custom_llm_provider": "openai",
|
||||
"description": "y",
|
||||
|
|
|
|||
|
|
@ -3166,18 +3166,34 @@ class TestCredentialDisplayName:
|
|||
repository.update_by_name.assert_not_awaited()
|
||||
assert litellm.credential_list == [_labeled_credential()]
|
||||
|
||||
def test_patch_accepts_the_same_credential_name_echoed_back(self, restore_credential_list, monkeypatch):
|
||||
@pytest.mark.parametrize(
|
||||
("patch_info", "expected_info"),
|
||||
[
|
||||
({}, {"custom_llm_provider": "openai"}),
|
||||
({"description": "y"}, {"custom_llm_provider": "openai", "description": "y"}),
|
||||
({"custom_llm_provider": "anthropic"}, {"custom_llm_provider": "anthropic"}),
|
||||
],
|
||||
)
|
||||
def test_patch_accepts_the_same_credential_name_echoed_back(
|
||||
self, restore_credential_list, monkeypatch, patch_info: dict[str, str], expected_info: dict[str, str]
|
||||
):
|
||||
monkeypatch.setattr(litellm, "credential_list", [_labeled_credential()])
|
||||
with _repository_holding(_labeled_credential()) as repository:
|
||||
response = _patch_credential(
|
||||
"openai-prod",
|
||||
{"credential_name": "openai-prod", "credential_values": {"api_key": "sk-new"}, "credential_info": {}},
|
||||
{
|
||||
"credential_name": "openai-prod",
|
||||
"credential_values": {"api_key": "sk-new"},
|
||||
"credential_info": patch_info,
|
||||
},
|
||||
)
|
||||
|
||||
assert response.status_code == 200, response.text
|
||||
assert [(c.credential_name, c.credential_values) for c in litellm.credential_list] == [
|
||||
("openai-prod", {"api_key": "sk-new"})
|
||||
]
|
||||
assert json.loads(repository.update_by_name.await_args.kwargs["data"]["credential_info"]) == expected_info
|
||||
assert litellm.credential_list[0].credential_info == expected_info
|
||||
|
||||
def test_patch_on_a_config_credential_is_rejected_as_config_owned(self, restore_credential_list, monkeypatch):
|
||||
config_credential = _labeled_credential(display_name=None).model_copy(update={"source": "config"})
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue