mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-28 06:23:07 +00:00
fix(bedrock): reject a malformed batch line whatever the upload's MIME type
The upload only converts, and so re-checks, batch files whose MIME type is on the allowlist. Falling back to the generic object name let a malformed file sent as application/x-jsonl skip both checks and land in S3 unchanged, so the object-name step now runs the same strict per-line parse and raises the 400.
This commit is contained in:
parent
5420ca2ed4
commit
f0eed8c56b
2 changed files with 26 additions and 12 deletions
|
|
@ -600,12 +600,11 @@ class BedrockFilesConfig(BaseAWSLLM, BaseFilesConfig):
|
|||
## 1. If jsonl, check if there's a model name
|
||||
file_content: Final = self._get_content_from_openai_file(extracted_file_data_content)
|
||||
|
||||
# Split into lines and parse each line as JSON. A file that is not JSONL gets the generic name below; the
|
||||
# upload's own conversion is what rejects a malformed batch file.
|
||||
with suppress(json.JSONDecodeError):
|
||||
openai_jsonl_content: Final = [json.loads(line) for line in file_content.splitlines() if line.strip()]
|
||||
if len(openai_jsonl_content) > 0:
|
||||
return self._get_s3_object_name_from_batch_jsonl(openai_jsonl_content)
|
||||
# Reject a malformed line here rather than falling back: the upload only converts (and so re-checks) files
|
||||
# whose MIME type is on the batch allowlist, so for any other MIME type this is the only check.
|
||||
openai_jsonl_content: Final = _parse_batch_jsonl(file_content)
|
||||
if len(openai_jsonl_content) > 0:
|
||||
return self._get_s3_object_name_from_batch_jsonl(openai_jsonl_content)
|
||||
|
||||
## 2. If not jsonl, store under a server-generated managed object name
|
||||
filename: Final = extracted_file_data.get("filename")
|
||||
|
|
|
|||
|
|
@ -4387,10 +4387,25 @@ class TestMalformedBatchJsonl:
|
|||
assert exc_info.value.status_code == 400
|
||||
assert "line 3" in exc_info.value.message
|
||||
|
||||
def test_object_name_inference_still_falls_back_for_a_non_json_file(self):
|
||||
from litellm.llms.bedrock.files.transformation import BedrockFilesConfig
|
||||
@pytest.mark.parametrize("content_type", ["application/jsonl", "application/x-jsonl"])
|
||||
def test_create_file_rejects_a_malformed_line_before_uploading(self, content_type: str):
|
||||
"""application/x-jsonl is not on the batch MIME allowlist, so the upload skips conversion for it; the line
|
||||
check must still run so the broken file is rejected instead of landing in S3 unchanged."""
|
||||
from litellm.llms.bedrock.common_utils import BedrockError
|
||||
|
||||
object_name = BedrockFilesConfig().get_object_name(
|
||||
{"content": b"just some text, not jsonl", "filename": "notes.txt"}, purpose="batch"
|
||||
)
|
||||
assert object_name.endswith("notes.txt")
|
||||
with respx.mock as router:
|
||||
any_request: Final = router.route()
|
||||
with pytest.raises(BedrockError) as exc_info:
|
||||
litellm.create_file(
|
||||
file=("batch.jsonl", _MALFORMED_BATCH_JSONL, content_type),
|
||||
purpose="batch",
|
||||
custom_llm_provider="bedrock",
|
||||
model="bedrock/amazon.nova-pro-v1:0",
|
||||
s3_bucket_name="litellm-batch-bucket",
|
||||
aws_region_name="us-west-2",
|
||||
aws_access_key_id="test-key-id",
|
||||
aws_secret_access_key="test-secret",
|
||||
)
|
||||
assert exc_info.value.status_code == 400
|
||||
assert "line 3" in exc_info.value.message
|
||||
assert not any_request.called
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue