fix(proxy): allow unblocking customers via /customer/update

update_end_user filtered out non-default values with v not in
([], {}, 0). Since False == 0 in Python, blocked: False was stripped
from the update payload. Treat bools as explicit values while preserving
the existing skips for empty containers and numeric zero

Fixes #34379
This commit is contained in:
Rāna(Bass Ver.) 2026-07-27 12:43:26 +08:00
parent 24123269cc
commit 703159eaab
2 changed files with 21 additions and 5 deletions

View file

@ -553,11 +553,7 @@ async def update_end_user(
# get non default values for key
non_default_values = {}
for k, v in data_json.items():
if v is not None and v not in (
[],
{},
0,
): # models default to [], spend defaults to 0, we should not reset these values
if v is not None and (isinstance(v, bool) or v not in ([], {}, 0)):
non_default_values[k] = v
## Get end user table data ##

View file

@ -85,6 +85,26 @@ def test_update_customer_success(mock_prisma_client, mock_user_api_key_auth):
assert response.json()["alias"] == "Updated Test User"
def test_update_customer_unblock(mock_prisma_client, mock_user_api_key_auth):
mock_end_user = LiteLLM_EndUserTable(user_id="test-user-1", blocked=True)
updated_mock_end_user = LiteLLM_EndUserTable(user_id="test-user-1", blocked=False)
mock_prisma_client.db.litellm_endusertable.find_first = AsyncMock(return_value=mock_end_user)
mock_prisma_client.db.litellm_endusertable.update = AsyncMock(return_value=updated_mock_end_user)
response = client.post(
"/customer/update",
json={"user_id": "test-user-1", "blocked": False},
headers={"Authorization": "Bearer test-key"},
)
assert response.status_code == 200
assert response.json()["blocked"] is False
update_mock = mock_prisma_client.db.litellm_endusertable.update
update_mock.assert_called_once()
assert update_mock.call_args.kwargs["data"]["blocked"] is False
def test_update_customer_not_found(mock_prisma_client, mock_user_api_key_auth):
"""
Test that update_end_user raises a 404 ProxyException when user_id does not exist.