@@ -2834,9 +2834,8 @@ async def test_set_usage_data_with_cache_tokens(sentry_init, capture_events):
28342834 assert span_data ["data" ][SPANDATA .GEN_AI_USAGE_INPUT_TOKENS_CACHE_WRITE ] == 20
28352835
28362836
2837- @pytest .mark .asyncio
28382837@pytest .mark .parametrize (
2839- "url, image_url_kwargs, expected_content" ,
2838+ "url,image_url_kwargs,expected_content" ,
28402839 [
28412840 pytest .param (
28422841 "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs" ,
@@ -2876,6 +2875,76 @@ async def test_set_usage_data_with_cache_tokens(sentry_init, capture_events):
28762875 ),
28772876 ],
28782877)
2878+ def test_image_url_base64_content_in_span (
2879+ sentry_init , capture_events , url , image_url_kwargs , expected_content
2880+ ):
2881+ from sentry_sdk .integrations .pydantic_ai .spans .ai_client import ai_client_span
2882+
2883+ sentry_init (
2884+ integrations = [PydanticAIIntegration ()],
2885+ traces_sample_rate = 1.0 ,
2886+ send_default_pii = True ,
2887+ )
2888+
2889+ events = capture_events ()
2890+
2891+ with sentry_sdk .start_transaction (op = "test" , name = "test" ):
2892+ image_url = ImageUrl (url = url , ** image_url_kwargs )
2893+ user_part = UserPromptPart (content = ["Look at this image:" , image_url ])
2894+ mock_msg = MagicMock ()
2895+ mock_msg .parts = [user_part ]
2896+ mock_msg .instructions = None
2897+
2898+ span = ai_client_span ([mock_msg ], None , None , None )
2899+ span .finish ()
2900+
2901+ (event ,) = events
2902+ chat_spans = [s for s in event ["spans" ] if s ["op" ] == "gen_ai.chat" ]
2903+ assert len (chat_spans ) >= 1
2904+ messages_data = _get_messages_from_span (chat_spans [0 ]["data" ])
2905+
2906+ found_image = False
2907+ for msg in messages_data :
2908+ if "content" not in msg :
2909+ continue
2910+ for content_item in msg ["content" ]:
2911+ if content_item .get ("type" ) == "image" :
2912+ found_image = True
2913+ assert content_item ["content" ] == expected_content
2914+
2915+ assert found_image , "Image content item should be found in messages data"
2916+
2917+
2918+ @pytest .mark .asyncio
2919+ @pytest .mark .parametrize (
2920+ "url, image_url_kwargs, expected_content" ,
2921+ [
2922+ pytest .param (
2923+ "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs" ,
2924+ {},
2925+ BLOB_DATA_SUBSTITUTE ,
2926+ id = "base64_data_url_redacted" ,
2927+ ),
2928+ pytest .param (
2929+ "https://example.com/image.png" ,
2930+ {},
2931+ "https://example.com/image.png" ,
2932+ id = "http_url_no_redaction" ,
2933+ ),
2934+ pytest .param (
2935+ "https://example.com/api?data=iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs" ,
2936+ {},
2937+ "https://example.com/api?data=iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs" ,
2938+ id = "http_url_with_base64_query_param" ,
2939+ ),
2940+ pytest .param (
2941+ "https://example.com/api?data=iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs" ,
2942+ {"media_type" : "image/png" },
2943+ "https://example.com/api?data=iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs" ,
2944+ id = "http_url_with_base64_query_param_and_media_type" ,
2945+ ),
2946+ ],
2947+ )
28792948async def test_invoke_agent_image_url (
28802949 sentry_init , capture_events , url , image_url_kwargs , expected_content
28812950):
0 commit comments