Setting the file. One moment.
Test Image Input · LLM To Bedrock · aws/agent-toolkit-for-aws · Skills Docs
ContentsBack to the top of the page 81
Creating Amazon Aurora Db Cluster With Instances
104
Routing Traffic With Route53 And CloudFront
Resilience Program Design
Creating API Gateway Stage
def _sdk_image_param_keys
— line 92
This file
Number 30.28
Position 28 of 35
Type Python
Size 6 KB
Lines 143 scripts/ test_image_input.py
Python · 143 lines · 6 KB
12
13 RAW = b " \xff\xd8\xff\xe0 fake-jpeg-bytes"
14
15
16 def test_jpg_extension_normalizes_to_jpeg ():
17 # Regression: `.jpg` passed through verbatim produced Converse `format: 'jpg'`
18 # and MIME `image/jpg`, both rejected. The smoke test hardcodes 'jpeg' and so
19 # never surfaced it.
20 assert ii.converse_format( "cat.jpg" ) == "jpeg"
21 assert ii.converse_format( "cat.jpeg" ) == "jpeg"
22 assert ii.mime_type( "cat.jpg" ) == "image/jpeg"
23 assert "image/jpg" not in ii.data_url( "cat.jpg" , RAW )
24
25
26 def test_extension_case_is_ignored ():
27 assert ii.converse_format( "CAT.JPG" ) == "jpeg"
28 assert ii.mime_type( "shot.PNG" ) == "image/png"
29
30
31 @pytest.mark.parametrize ( "name,fmt" , [
32 ( "a.png" , "png" ), ( "a.gif" , "gif" ), ( "a.webp" , "webp" ),
33 ])
34 def test_other_supported_formats (name, fmt):
35 assert ii.converse_format(name) == fmt
36 assert ii.mime_type(name) == f "image/ { fmt } "
37
38
39 @pytest.mark.parametrize ( "name" , [ "a.bmp" , "a.tiff" , "a.svg" , "a.heic" , "noext" ])
40 def test_unsupported_types_raise_rather_than_guess (name):
41 # Silently passing an unsupported extension through would produce an opaque
42 # API rejection at eval time instead of a clear failure here.
43 with pytest.raises( ValueError , match = "unsupported image type" ):
44 ii.converse_format(name)
45
46
47 def test_responses_message_is_wrapped_as_a_user_message ():
48 # Regression: the per-case loop passed a bare [{'type': 'input_text', ...}]
49 # list as `input`, which is not a valid Responses request.
50 msg = ii.responses_message( "describe" , "cat.jpg" , RAW )
51 assert msg[ "role" ] == "user"
52 assert isinstance (msg[ "content" ], list )
53 kinds = [b[ "type" ] for b in msg[ "content" ]]
54 assert kinds == [ "input_text" , "input_image" ]
55 assert msg[ "content" ][ 1 ][ "image_url" ].startswith( "data:image/jpeg;base64," )
56 assert base64.b64encode( RAW ).decode() in msg[ "content" ][ 1 ][ "image_url" ]
57
58
59 def test_responses_message_text_only_omits_the_image_block ():
60 msg = ii.responses_message( "describe" )
61 assert msg[ "role" ] == "user"
62 assert [b[ "type" ] for b in msg[ "content" ]] == [ "input_text" ]
63
64
65 def test_converse_message_puts_image_before_text ():
66 msg = ii.converse_message( "describe" , "cat.jpg" , RAW )
67 assert msg[ "role" ] == "user"
68 assert list (msg[ "content" ][ 0 ]) == [ "image" ]
69 assert msg[ "content" ][ 0 ][ "image" ][ "format" ] == "jpeg"
70 assert msg[ "content" ][ 0 ][ "image" ][ "source" ][ "bytes" ] is RAW
71 assert msg[ "content" ][ 1 ] == { "text" : "describe" }
72
73
74 def test_converse_message_text_only ():
75 assert ii.converse_message( "describe" ) == {
76 "role" : "user" , "content" : [{ "text" : "describe" }]}
77
78
79 @pytest.mark.parametrize ( "fn" , [ii.converse_message, ii.responses_message])
80 def test_image_path_without_bytes_is_an_error (fn):
81 with pytest.raises( ValueError , match = "raw image bytes" ):
82 fn( "describe" , "cat.jpg" , None )
83
84
85 def test_responses_image_block_sets_detail ():
86 # Regression: `detail` is Required on ResponseInputImageParam in the pinned SDK,
87 # and omitting it is a contract violation a TypedDict will not catch at runtime.
88 block = ii.responses_message( "describe" , "cat.jpg" , RAW )[ "content" ][ 1 ]
89 assert block[ "detail" ] == "auto"
90
91
92 def _sdk_image_param_keys () -> tuple[set[ str ], set[ str ]]:
93 """(required, all) keys of ResponseInputImageParam, read from the pinned SDK.
94
95 `__required_keys__` is unusable here: the class is declared `total=False` with
96 per-field `Required[...]` markers, which CPython 3.11 does not fold into
97 `__required_keys__` — it reports every key as optional. The annotation origin
98 does carry the marker, so read requiredness from there.
99 """
100 import typing_extensions as te
101 from openai.types.responses import ResponseInputImageParam
102
103 hints = te.get_type_hints(ResponseInputImageParam, include_extras = True )
104 required = {k for k, v in hints.items() if te.get_origin(v) is te.Required}
105 return required, set (hints)
106
107
108 def test_responses_image_block_satisfies_the_pinned_sdk_required_fields ():
109 # Derive the requirement from the installed SDK rather than restating it, so a
110 # future SDK bump that adds a required field fails here instead of at runtime.
111 required, known = _sdk_image_param_keys()
112 assert "detail" in required, "SDK no longer marks detail required — revisit this test"
113 block = ii.responses_message( "describe" , "cat.jpg" , RAW )[ "content" ][ 1 ]
114 missing = required - set (block)
115 assert not missing, f "image block missing SDK-required field(s): { sorted (missing) } "
116 unknown = set (block) - known
117 assert not unknown, f "image block has field(s) the SDK does not define: { sorted (unknown) } "
118
119
120 @pytest.mark.parametrize ( "detail" , [ "low" , "high" , "auto" , "original" ])
121 def test_all_sdk_detail_levels_accepted (detail):
122 block = ii.responses_message( "d" , "cat.png" , RAW , detail = detail)[ "content" ][ 1 ]
123 assert block[ "detail" ] == detail
124
125
126 def test_invalid_detail_rejected ():
127 with pytest.raises( ValueError , match = "invalid image detail" ):
128 ii.responses_message( "d" , "cat.png" , RAW , detail = "ultra" )
129
130
131 def test_detail_levels_match_the_pinned_sdk_literal ():
132 import typing_extensions as te
133 from openai.types.responses import ResponseInputImageParam
134 hints = te.get_type_hints(ResponseInputImageParam, include_extras = True )
135 literal = te.get_args(te.get_args(hints[ "detail" ])[ 0 ]) # unwrap Required[Literal[...]]
136 assert set (literal) == set (ii. DETAIL_LEVELS )
137
138
139 def test_text_only_message_has_no_detail_key ():
140 # detail belongs to the image block only; a stray key on the text block would
141 # be an unknown field.
142 msg = ii.responses_message( "describe" )
143 assert "detail" not in msg[ "content" ][ 0 ]