mirror of
https://github.com/tiennm99/litellm.git
synced 2026-07-10 15:03:36 +00:00
fix unsupported operand type(s) for +=: 'NoneType' and 'str' on clientside auth creds for responses (#13293)
This commit is contained in:
+2
-2
@@ -1416,8 +1416,8 @@ class Router:
|
||||
dynamic_litellm_params = get_dynamic_litellm_params(
|
||||
litellm_params=litellm_params, request_kwargs=kwargs
|
||||
)
|
||||
metadata = kwargs.get("metadata", {})
|
||||
model_group = cast(str, metadata.get("model_group"))
|
||||
# Use deployment model_name as model_group for generating model_id
|
||||
model_group = deployment["model_name"]
|
||||
_model_id = self._generate_model_id(
|
||||
model_group=model_group, litellm_params=dynamic_litellm_params
|
||||
)
|
||||
|
||||
@@ -1332,3 +1332,112 @@ def test_init_auto_router_deployment_duplicate_model_name(mock_auto_router, mode
|
||||
with pytest.raises(ValueError, match="Auto-router deployment test-auto-router already exists"):
|
||||
router.init_auto_router_deployment(deployment)
|
||||
|
||||
|
||||
def test_generate_model_id_with_deployment_model_name(model_list):
|
||||
"""Test that _generate_model_id works correctly with deployment model_name and handles None values properly"""
|
||||
router = Router(model_list=model_list)
|
||||
|
||||
# Test case 1: Normal case with valid model_group and litellm_params
|
||||
model_group = "gpt-4.1"
|
||||
litellm_params = {
|
||||
"model": "gpt-4.1",
|
||||
"api_key": "test_key",
|
||||
"api_base": "https://api.openai.com/v1"
|
||||
}
|
||||
|
||||
try:
|
||||
result = router._generate_model_id(model_group=model_group, litellm_params=litellm_params)
|
||||
assert isinstance(result, str)
|
||||
assert len(result) > 0
|
||||
print(f"✓ Success with valid model_group: {result}")
|
||||
except Exception as e:
|
||||
pytest.fail(f"Failed with valid model_group: {e}")
|
||||
|
||||
# Test case 2: Edge case with None model_group (this should fail as expected - our fix prevents this from happening)
|
||||
try:
|
||||
result = router._generate_model_id(model_group=None, litellm_params=litellm_params)
|
||||
pytest.fail("Expected TypeError when model_group is None - this confirms our fix is needed")
|
||||
except TypeError as e:
|
||||
assert "unsupported operand type(s) for +=" in str(e)
|
||||
print(f"✓ Correctly failed with None model_group (as expected): {e}")
|
||||
except Exception as e:
|
||||
pytest.fail(f"Unexpected error with None model_group: {e}")
|
||||
|
||||
# Test case 3: Edge case with None key in litellm_params
|
||||
litellm_params_with_none_key = {
|
||||
"model": "gpt-4.1",
|
||||
"api_key": "test_key",
|
||||
None: "should_be_skipped" # This should be handled gracefully
|
||||
}
|
||||
|
||||
try:
|
||||
result = router._generate_model_id(model_group=model_group, litellm_params=litellm_params_with_none_key)
|
||||
assert isinstance(result, str)
|
||||
assert len(result) > 0
|
||||
print(f"✓ Success with None key in litellm_params: {result}")
|
||||
except Exception as e:
|
||||
pytest.fail(f"Failed with None key in litellm_params: {e}")
|
||||
|
||||
# Test case 4: Edge case with empty litellm_params
|
||||
try:
|
||||
result = router._generate_model_id(model_group=model_group, litellm_params={})
|
||||
assert isinstance(result, str)
|
||||
assert len(result) > 0
|
||||
print(f"✓ Success with empty litellm_params: {result}")
|
||||
except Exception as e:
|
||||
pytest.fail(f"Failed with empty litellm_params: {e}")
|
||||
|
||||
# Test case 5: Verify that the same inputs produce the same result (deterministic)
|
||||
result1 = router._generate_model_id(model_group=model_group, litellm_params=litellm_params)
|
||||
result2 = router._generate_model_id(model_group=model_group, litellm_params=litellm_params)
|
||||
assert result1 == result2, "Model ID generation should be deterministic"
|
||||
|
||||
print("✓ All _generate_model_id tests passed!")
|
||||
|
||||
|
||||
def test_handle_clientside_credential_with_deployment_model_name(model_list):
|
||||
"""Test that _handle_clientside_credential uses deployment model_name correctly"""
|
||||
router = Router(model_list=model_list)
|
||||
|
||||
# Mock deployment with model_name
|
||||
deployment = {
|
||||
"model_name": "gpt-4.1",
|
||||
"litellm_params": {
|
||||
"model": "gpt-4.1",
|
||||
"api_key": "test_key"
|
||||
}
|
||||
}
|
||||
|
||||
# Mock kwargs with empty metadata (simulating the original issue)
|
||||
kwargs = {
|
||||
"metadata": {}, # Empty metadata, no model_group
|
||||
"litellm_params": {
|
||||
"api_key": "client_side_key",
|
||||
"api_base": "https://api.openai.com/v1"
|
||||
}
|
||||
}
|
||||
|
||||
# Mock dynamic_litellm_params that would be returned by get_dynamic_litellm_params
|
||||
dynamic_litellm_params = {
|
||||
"api_key": "client_side_key",
|
||||
"api_base": "https://api.openai.com/v1"
|
||||
}
|
||||
|
||||
# Test that the method doesn't fail when metadata is empty
|
||||
try:
|
||||
# This would normally call _generate_model_id internally
|
||||
# We're testing that the fix prevents the TypeError
|
||||
model_group = deployment["model_name"] # This is what our fix does
|
||||
assert model_group == "gpt-4.1"
|
||||
|
||||
# Verify that _generate_model_id works with this model_group
|
||||
result = router._generate_model_id(model_group=model_group, litellm_params=dynamic_litellm_params)
|
||||
assert isinstance(result, str)
|
||||
assert len(result) > 0
|
||||
|
||||
print(f"✓ Success with deployment model_name: {result}")
|
||||
except Exception as e:
|
||||
pytest.fail(f"Failed with deployment model_name: {e}")
|
||||
|
||||
print("✓ _handle_clientside_credential test passed!")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user