Skip to content

Commit fb584c4

Browse files
committed
Add support for bucketOwner; update tests
1 parent 9631781 commit fb584c4

File tree

5 files changed

+41
-134
lines changed

5 files changed

+41
-134
lines changed

pydantic_ai_slim/pydantic_ai/models/bedrock.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -736,7 +736,10 @@ async def _map_user_prompt( # noqa: C901
736736
elif isinstance(item, ImageUrl | DocumentUrl | VideoUrl):
737737
source: dict[str, Any]
738738
if item.url.startswith('s3://'):
739-
source = {'s3Location': {'uri': item.url}}
739+
s3_location: dict[str, str] = {'uri': item.url.split('?')[0]}
740+
if '?bucketOwner=' in item.url:
741+
s3_location['bucketOwner'] = item.url.split('?bucketOwner=')[1]
742+
source = {'s3Location': s3_location}
740743
else:
741744
downloaded_item = await download_item(item, data_format='bytes', type_format='extension')
742745
source = {'bytes': downloaded_item['data']}

tests/models/cassettes/test_bedrock/test_s3_document_url_input.yaml

Lines changed: 0 additions & 42 deletions
This file was deleted.

tests/models/cassettes/test_bedrock/test_s3_image_url_input.yaml

Lines changed: 0 additions & 42 deletions
This file was deleted.

tests/models/cassettes/test_bedrock/test_s3_video_url_input.yaml

Lines changed: 0 additions & 42 deletions
This file was deleted.

tests/models/test_bedrock.py

Lines changed: 37 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -748,7 +748,7 @@ async def test_s3_image_url_input(bedrock_provider: BedrockProvider):
748748
ModelRequest(parts=[UserPromptPart(content=['What is in this image?', image_url])]),
749749
]
750750

751-
_, bedrock_messages = await model._map_messages(req, ModelRequestParameters()) # type: ignore[reportPrivateUsage]
751+
_, bedrock_messages = await model._map_messages(req, ModelRequestParameters(), None) # type: ignore[reportPrivateUsage]
752752

753753
assert bedrock_messages == snapshot(
754754
[
@@ -773,13 +773,11 @@ async def test_s3_video_url_input(bedrock_provider: BedrockProvider):
773773
model = BedrockConverseModel('us.amazon.nova-pro-v1:0', provider=bedrock_provider)
774774
video_url = VideoUrl(url='s3://my-bucket/videos/test-video.mp4', media_type='video/mp4')
775775

776-
# Create a ModelRequest with the S3 video URL
777776
req = [
778777
ModelRequest(parts=[UserPromptPart(content=['Describe this video', video_url])]),
779778
]
780779

781-
# Call the mapping function directly
782-
_, bedrock_messages = await model._map_messages(req, ModelRequestParameters()) # type: ignore[reportPrivateUsage]
780+
_, bedrock_messages = await model._map_messages(req, ModelRequestParameters(), None) # type: ignore[reportPrivateUsage]
783781

784782
assert bedrock_messages == snapshot(
785783
[
@@ -804,13 +802,11 @@ async def test_s3_document_url_input(bedrock_provider: BedrockProvider):
804802
model = BedrockConverseModel('anthropic.claude-v2', provider=bedrock_provider)
805803
document_url = DocumentUrl(url='s3://my-bucket/documents/test-doc.pdf', media_type='application/pdf')
806804

807-
# Create a ModelRequest with the S3 document URL
808805
req = [
809806
ModelRequest(parts=[UserPromptPart(content=['What is the main content on this document?', document_url])]),
810807
]
811808

812-
# Call the mapping function directly
813-
_, bedrock_messages = await model._map_messages(req, ModelRequestParameters()) # type: ignore[reportPrivateUsage]
809+
_, bedrock_messages = await model._map_messages(req, ModelRequestParameters(), None) # type: ignore[reportPrivateUsage]
814810

815811
assert bedrock_messages == snapshot(
816812
[
@@ -831,6 +827,40 @@ async def test_s3_document_url_input(bedrock_provider: BedrockProvider):
831827
)
832828

833829

830+
async def test_s3_url_with_bucket_owner(bedrock_provider: BedrockProvider):
831+
"""Test that s3:// URLs with bucketOwner parameter are parsed correctly."""
832+
model = BedrockConverseModel('us.amazon.nova-pro-v1:0', provider=bedrock_provider)
833+
image_url = ImageUrl(url='s3://my-bucket/images/test-image.jpg?bucketOwner=123456789012', media_type='image/jpeg')
834+
835+
req = [
836+
ModelRequest(parts=[UserPromptPart(content=['What is in this image?', image_url])]),
837+
]
838+
839+
_, bedrock_messages = await model._map_messages(req, ModelRequestParameters(), None) # type: ignore[reportPrivateUsage]
840+
841+
assert bedrock_messages == snapshot(
842+
[
843+
{
844+
'role': 'user',
845+
'content': [
846+
{'text': 'What is in this image?'},
847+
{
848+
'image': {
849+
'format': 'jpeg',
850+
'source': {
851+
's3Location': {
852+
'uri': 's3://my-bucket/images/test-image.jpg',
853+
'bucketOwner': '123456789012',
854+
}
855+
},
856+
}
857+
},
858+
],
859+
}
860+
]
861+
)
862+
863+
834864
@pytest.mark.vcr()
835865
async def test_text_as_binary_content_input(allow_model_requests: None, bedrock_provider: BedrockProvider):
836866
m = BedrockConverseModel('us.amazon.nova-pro-v1:0', provider=bedrock_provider)

0 commit comments

Comments
 (0)