Skip to content

Commit 5114533

Browse files
ref(openai): Separate sync and async Responses patches
1 parent a073290 commit 5114533

1 file changed

Lines changed: 81 additions & 43 deletions

File tree

sentry_sdk/integrations/openai.py

Lines changed: 81 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1255,7 +1255,7 @@ async def _sentry_patched_create_async(*args: "Any", **kwargs: "Any") -> "Any":
12551255
return _sentry_patched_create_async
12561256

12571257

1258-
def _new_responses_create_common(f: "Any", *args: "Any", **kwargs: "Any") -> "Any":
1258+
def _new_sync_responses_create(f: "Any", *args: "Any", **kwargs: "Any") -> "Any":
12591259
integration = sentry_sdk.get_client().get_integration(OpenAIIntegration)
12601260
if integration is None:
12611261
return f(*args, **kwargs)
@@ -1278,7 +1278,14 @@ def _new_responses_create_common(f: "Any", *args: "Any", **kwargs: "Any") -> "An
12781278
_set_responses_api_input_data(span, kwargs, integration)
12791279

12801280
start_time = time.perf_counter()
1281-
response = yield f, args, kwargs
1281+
1282+
try:
1283+
response = f(*args, **kwargs)
1284+
except Exception as exc:
1285+
exc_info = sys.exc_info()
1286+
with capture_internal_exceptions():
1287+
_capture_exception(exc)
1288+
reraise(*exc_info)
12821289

12831290
# Attribute check to fail gracefully if the attribute is not present in future `openai` versions.
12841291
if isinstance(response, Stream) and hasattr(response, "_iterator"):
@@ -1321,68 +1328,99 @@ def _new_responses_create_common(f: "Any", *args: "Any", **kwargs: "Any") -> "An
13211328
return response
13221329

13231330

1324-
def _wrap_responses_create(f: "Any") -> "Any":
1325-
def _execute_sync(f: "Any", *args: "Any", **kwargs: "Any") -> "Any":
1326-
gen = _new_responses_create_common(f, *args, **kwargs)
1331+
async def _new_async_responses_create(f: "Any", *args: "Any", **kwargs: "Any") -> "Any":
1332+
integration = sentry_sdk.get_client().get_integration(OpenAIIntegration)
1333+
if integration is None:
1334+
return f(*args, **kwargs)
13271335

1328-
try:
1329-
f, args, kwargs = next(gen)
1330-
except StopIteration as e:
1331-
return e.value
1336+
model = kwargs.get("model")
13321337

1333-
try:
1334-
try:
1335-
result = f(*args, **kwargs)
1336-
except Exception as e:
1337-
exc_info = sys.exc_info()
1338-
with capture_internal_exceptions():
1339-
_capture_exception(e)
1340-
reraise(*exc_info)
1338+
span = sentry_sdk.start_span(
1339+
op=consts.OP.GEN_AI_RESPONSES,
1340+
name=f"responses {model}",
1341+
origin=OpenAIIntegration.origin,
1342+
)
1343+
span.__enter__()
13411344

1342-
return gen.send(result)
1343-
except StopIteration as e:
1344-
return e.value
1345+
span.set_data(SPANDATA.GEN_AI_SYSTEM, "openai")
1346+
1347+
# Same bool handling as in https://github.com/openai/openai-python/blob/acd0c54d8a68efeedde0e5b4e6c310eef1ce7867/src/openai/resources/responses/responses.py#L940
1348+
is_streaming_response = kwargs.get("stream", False) or False
1349+
span.set_data(SPANDATA.GEN_AI_RESPONSE_STREAMING, is_streaming_response)
1350+
1351+
_set_responses_api_input_data(span, kwargs, integration)
1352+
1353+
start_time = time.perf_counter()
1354+
1355+
try:
1356+
response = await f(*args, **kwargs)
1357+
except Exception as exc:
1358+
exc_info = sys.exc_info()
1359+
with capture_internal_exceptions():
1360+
_capture_exception(exc)
1361+
reraise(*exc_info)
1362+
1363+
# Attribute check to fail gracefully if the attribute is not present in future `openai` versions.
1364+
if isinstance(response, Stream) and hasattr(response, "_iterator"):
1365+
input = kwargs.get("input")
1366+
1367+
if input is not None and isinstance(input, str):
1368+
input = [input]
1369+
1370+
response._iterator = _wrap_synchronous_responses_event_iterator(
1371+
span=span,
1372+
integration=integration,
1373+
start_time=start_time,
1374+
input=input,
1375+
response=response,
1376+
old_iterator=response._iterator,
1377+
finish_span=True,
1378+
)
1379+
1380+
# Attribute check to fail gracefully if the attribute is not present in future `openai` versions.
1381+
elif isinstance(response, AsyncStream) and hasattr(response, "_iterator"):
1382+
input = kwargs.get("input")
13451383

1384+
if input is not None and isinstance(input, str):
1385+
input = [input]
1386+
1387+
response._iterator = _wrap_asynchronous_responses_event_iterator(
1388+
span=span,
1389+
integration=integration,
1390+
start_time=start_time,
1391+
input=input,
1392+
response=response,
1393+
old_iterator=response._iterator,
1394+
finish_span=True,
1395+
)
1396+
else:
1397+
_set_responses_api_output_data(
1398+
span, response, kwargs, integration, finish_span=True
1399+
)
1400+
1401+
return response
1402+
1403+
1404+
def _wrap_responses_create(f: "Any") -> "Any":
13461405
@wraps(f)
13471406
def _sentry_patched_create_sync(*args: "Any", **kwargs: "Any") -> "Any":
13481407
integration = sentry_sdk.get_client().get_integration(OpenAIIntegration)
13491408
if integration is None:
13501409
return f(*args, **kwargs)
13511410

1352-
return _execute_sync(f, *args, **kwargs)
1411+
return _new_sync_responses_create(f, *args, **kwargs)
13531412

13541413
return _sentry_patched_create_sync
13551414

13561415

13571416
def _wrap_async_responses_create(f: "Any") -> "Any":
1358-
async def _execute_async(f: "Any", *args: "Any", **kwargs: "Any") -> "Any":
1359-
gen = _new_responses_create_common(f, *args, **kwargs)
1360-
1361-
try:
1362-
f, args, kwargs = next(gen)
1363-
except StopIteration as e:
1364-
return await e.value
1365-
1366-
try:
1367-
try:
1368-
result = await f(*args, **kwargs)
1369-
except Exception as e:
1370-
exc_info = sys.exc_info()
1371-
with capture_internal_exceptions():
1372-
_capture_exception(e)
1373-
reraise(*exc_info)
1374-
1375-
return gen.send(result)
1376-
except StopIteration as e:
1377-
return e.value
1378-
13791417
@wraps(f)
13801418
async def _sentry_patched_responses_async(*args: "Any", **kwargs: "Any") -> "Any":
13811419
integration = sentry_sdk.get_client().get_integration(OpenAIIntegration)
13821420
if integration is None:
13831421
return await f(*args, **kwargs)
13841422

1385-
return await _execute_async(f, *args, **kwargs)
1423+
return await _new_async_responses_create(f, *args, **kwargs)
13861424

13871425
return _sentry_patched_responses_async
13881426

0 commit comments

Comments
 (0)