Skip to content

Commit c43f5b4

Browse files
committed
Test async responses api
1 parent 4e16e04 commit c43f5b4

File tree

1 file changed

+76
-0
lines changed

1 file changed

+76
-0
lines changed

tests/integrations/openai/test_openai.py

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1074,3 +1074,79 @@ def test_error_in_responses_api(sentry_init, capture_events):
10741074
error_event["contexts"]["trace"]["trace_id"]
10751075
== transaction_event["contexts"]["trace"]["trace_id"]
10761076
)
1077+
1078+
1079+
@pytest.mark.skipif(SKIP_RESPONSES_TESTS, reason="Responses API not available")
1080+
async def test_ai_client_span_responses_async_api(sentry_init, capture_events):
1081+
sentry_init(
1082+
integrations=[OpenAIIntegration(include_prompts=True)],
1083+
traces_sample_rate=1.0,
1084+
send_default_pii=True,
1085+
)
1086+
events = capture_events()
1087+
1088+
client = AsyncOpenAI(api_key="z")
1089+
client.responses._post = mock.Mock(return_value=EXAMPLE_RESPONSE)
1090+
1091+
with start_transaction(name="openai tx"):
1092+
await client.responses.create(
1093+
model="gpt-4o",
1094+
instructions="You are a coding assistant that talks like a pirate.",
1095+
input="How do I check if a Python object is an instance of a class?",
1096+
)
1097+
1098+
(transaction,) = events
1099+
spans = transaction["spans"]
1100+
1101+
assert len(spans) == 1
1102+
assert spans[0]["op"] == "gen_ai.responses"
1103+
assert spans[0]["origin"] == "auto.ai.openai"
1104+
assert spans[0]["data"] == {
1105+
"gen_ai.request.messages": "How do I check if a Python object is an instance of a class?",
1106+
"gen_ai.request.model": "gpt-4o",
1107+
"gen_ai.usage.input_tokens": 20,
1108+
"gen_ai.usage.input_tokens.cached": 5,
1109+
"gen_ai.usage.output_tokens": 10,
1110+
"gen_ai.usage.output_tokens.reasoning": 8,
1111+
"gen_ai.usage.total_tokens": 30,
1112+
"gen_ai.response.text": '[{"id": "message-id", "content": [{"annotations": [], "text": "the model response", "type": "output_text"}], "role": "assistant", "status": "completed", "type": "message"}]',
1113+
"thread.id": mock.ANY,
1114+
"thread.name": mock.ANY,
1115+
}
1116+
1117+
1118+
@pytest.mark.skipif(SKIP_RESPONSES_TESTS, reason="Responses API not available")
1119+
async def test_error_in_responses_async_api(sentry_init, capture_events):
1120+
sentry_init(
1121+
integrations=[OpenAIIntegration(include_prompts=True)],
1122+
traces_sample_rate=1.0,
1123+
send_default_pii=True,
1124+
)
1125+
events = capture_events()
1126+
1127+
client = AsyncOpenAI(api_key="z")
1128+
client.responses._post = mock.Mock(
1129+
side_effect=OpenAIError("API rate limit reached")
1130+
)
1131+
1132+
with start_transaction(name="openai tx"):
1133+
with pytest.raises(OpenAIError):
1134+
await client.responses.create(
1135+
model="gpt-4o",
1136+
instructions="You are a coding assistant that talks like a pirate.",
1137+
input="How do I check if a Python object is an instance of a class?",
1138+
)
1139+
1140+
(error_event, transaction_event) = events
1141+
1142+
assert transaction_event["type"] == "transaction"
1143+
# make sure the span where the error occurred is captured
1144+
assert transaction_event["spans"][0]["op"] == "gen_ai.responses"
1145+
1146+
assert error_event["level"] == "error"
1147+
assert error_event["exception"]["values"][0]["type"] == "OpenAIError"
1148+
1149+
assert (
1150+
error_event["contexts"]["trace"]["trace_id"]
1151+
== transaction_event["contexts"]["trace"]["trace_id"]
1152+
)

0 commit comments

Comments
 (0)