-
-
Notifications
You must be signed in to change notification settings - Fork 11.2k
fix(s3_v2): use prepared URL for SigV4-signed S3 requests #25074
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -292,6 +292,50 @@ def test_s3_v2_virtual_hosted_style(self, mock_periodic_flush, mock_create_task) | |||||||||||
|
|
||||||||||||
| assert result == {"downloaded": "data"} | ||||||||||||
|
|
||||||||||||
| @patch("asyncio.create_task") | ||||||||||||
| @patch("litellm.integrations.s3_v2.CustomBatchLogger.periodic_flush") | ||||||||||||
| def test_s3_v2_put_url_encodes_spaces_in_object_key( | ||||||||||||
| self, mock_periodic_flush, mock_create_task | ||||||||||||
| ): | ||||||||||||
| import requests | ||||||||||||
| from unittest.mock import AsyncMock | ||||||||||||
|
|
||||||||||||
| from litellm.types.integrations.s3_v2 import s3BatchLoggingElement | ||||||||||||
|
|
||||||||||||
| mock_periodic_flush.return_value = None | ||||||||||||
| mock_create_task.return_value = None | ||||||||||||
|
|
||||||||||||
| mock_response = MagicMock() | ||||||||||||
| mock_response.status_code = 200 | ||||||||||||
| mock_response.raise_for_status = MagicMock() | ||||||||||||
|
|
||||||||||||
| s3_object_key = "My Team/2025-09-14/test-key.json" | ||||||||||||
| test_element = s3BatchLoggingElement( | ||||||||||||
| s3_object_key=s3_object_key, | ||||||||||||
| payload={"test": "data"}, | ||||||||||||
| s3_object_download_filename="test-file.json", | ||||||||||||
| ) | ||||||||||||
|
|
||||||||||||
| s3_logger = S3Logger( | ||||||||||||
| s3_bucket_name="test-bucket", | ||||||||||||
| s3_endpoint_url="https://s3.amazonaws.com", | ||||||||||||
| s3_aws_access_key_id="test-key", | ||||||||||||
| s3_aws_secret_access_key="test-secret", | ||||||||||||
| s3_region_name="us-east-1", | ||||||||||||
| ) | ||||||||||||
| s3_logger.async_httpx_client = AsyncMock() | ||||||||||||
| s3_logger.async_httpx_client.put.return_value = mock_response | ||||||||||||
|
|
||||||||||||
| asyncio.run(s3_logger.async_upload_data_to_s3(test_element)) | ||||||||||||
|
|
||||||||||||
| call_args = s3_logger.async_httpx_client.put.call_args | ||||||||||||
| assert call_args is not None | ||||||||||||
| actual_url = call_args[0][0] | ||||||||||||
| raw_url = f"https://s3.amazonaws.com/test-bucket/{s3_object_key}" | ||||||||||||
| expected_url = requests.Request("PUT", raw_url).prepare().url | ||||||||||||
| assert actual_url == expected_url | ||||||||||||
| assert " " not in actual_url | ||||||||||||
|
Comment on lines
+297
to
+337
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
The fix applies |
||||||||||||
|
|
||||||||||||
| @pytest.mark.asyncio | ||||||||||||
|
Comment on lines
+338
to
339
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
PEP 8 requires two blank lines before a top-level function definition. There is currently only one blank line between the end of
Suggested change
|
||||||||||||
| async def test_async_log_event_skips_when_standard_logging_object_missing(): | ||||||||||||
| """ | ||||||||||||
|
|
||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Per the project's style guide (CLAUDE.md), imports inside methods make dependencies harder to trace and hurt readability.
requests,AsyncMock, ands3BatchLoggingElementshould be declared at the top of the file alongside the existing imports.The top of the file already imports
MagicMockandpatchfromunittest.mock;AsyncMockcan simply be added to that same import:Then remove the three
importlines from inside the test method body.Context Used: CLAUDE.md (source)
Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!