mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-26 01:12:21 +00:00
fix(images): cast n to int from multipart form data in image edit
Multipart/form-data delivers all fields as strings, so n='1' instead of the integer 1. Azure's backend validates n with integer comparisons (e.g. 1 <= n <= 10) and raises: TypeError: '<=' not supported between instances of 'str' and 'int' which propagates as APIError: AzureException APIError - '<=' not supported between instances of 'str' and 'int'. Fix: coerce n from str to int (or drop it on invalid input) inside get_requested_image_edit_optional_param() before the params are forwarded to the provider. Fixes #27978
This commit is contained in:
parent
e59e34bed3
commit
194b81d2ad
2 changed files with 55 additions and 0 deletions
|
|
@ -80,6 +80,14 @@ class ImageEditRequestUtils:
|
|||
filtered_params = {
|
||||
k: v for k, v in params.items() if k in valid_keys and v is not None
|
||||
}
|
||||
# Multipart form data delivers all fields as strings; coerce n to int so
|
||||
# Azure's backend validation (which does integer comparisons) doesn't fail
|
||||
# with "TypeError: '<=' not supported between instances of 'str' and 'int'".
|
||||
if "n" in filtered_params and isinstance(filtered_params["n"], str):
|
||||
try:
|
||||
filtered_params["n"] = int(filtered_params["n"])
|
||||
except (ValueError, TypeError):
|
||||
filtered_params.pop("n", None)
|
||||
return cast(ImageEditOptionalRequestParams, filtered_params)
|
||||
|
||||
@staticmethod
|
||||
|
|
|
|||
|
|
@ -773,3 +773,50 @@ async def test_image_edit_array_handling():
|
|||
|
||||
# Verify that both calls were made to the API
|
||||
assert mock_post.call_count == 2
|
||||
|
||||
|
||||
def test_image_edit_n_coercion_from_string():
|
||||
"""
|
||||
Regression test for https://github.com/BerriAI/litellm/issues/27978.
|
||||
|
||||
When the proxy receives a multipart/form-data request, all form fields
|
||||
arrive as strings (e.g. n='1' instead of n=1). Azure's backend validates
|
||||
n as an integer and raises:
|
||||
TypeError: '<=' not supported between instances of 'str' and 'int'
|
||||
unless litellm coerces the value before forwarding the request.
|
||||
"""
|
||||
from litellm.images.utils import ImageEditRequestUtils
|
||||
|
||||
# Simulate what _read_request_body returns for a multipart form upload
|
||||
params_from_form = {
|
||||
"n": "1", # string, as delivered by multipart form data
|
||||
"model": "azure/gpt-image-2",
|
||||
"prompt": "make it ghibli",
|
||||
"size": "1024x1024",
|
||||
}
|
||||
|
||||
result = ImageEditRequestUtils.get_requested_image_edit_optional_param(
|
||||
params_from_form
|
||||
)
|
||||
|
||||
assert result["n"] == 1, f"Expected n=1 (int), got n={result['n']!r}"
|
||||
assert isinstance(result["n"], int), f"Expected int, got {type(result['n'])}"
|
||||
|
||||
|
||||
def test_image_edit_n_coercion_invalid_string():
|
||||
"""n cannot be parsed → it is dropped silently rather than crashing."""
|
||||
from litellm.images.utils import ImageEditRequestUtils
|
||||
|
||||
params = {"n": "not_a_number", "model": "azure/gpt-image-2", "prompt": "test"}
|
||||
result = ImageEditRequestUtils.get_requested_image_edit_optional_param(params)
|
||||
assert "n" not in result, "Invalid n string should be dropped, not passed through"
|
||||
|
||||
|
||||
def test_image_edit_n_already_int():
|
||||
"""When n is already an int (direct SDK call), it passes through unchanged."""
|
||||
from litellm.images.utils import ImageEditRequestUtils
|
||||
|
||||
params = {"n": 2, "model": "azure/gpt-image-2", "prompt": "test"}
|
||||
result = ImageEditRequestUtils.get_requested_image_edit_optional_param(params)
|
||||
assert result["n"] == 2
|
||||
assert isinstance(result["n"], int)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue