@@ -670,7 +670,7 @@ def _set_common_output_data(
670670 span .__exit__ (None , None , None )
671671
672672
673- def _new_chat_completion_common (f : "Any" , * args : "Any" , ** kwargs : "Any" ) -> "Any" :
673+ def _new_sync_chat_completion (f : "Any" , * args : "Any" , ** kwargs : "Any" ) -> "Any" :
674674 integration = sentry_sdk .get_client ().get_integration (OpenAIIntegration )
675675 if integration is None :
676676 return f (* args , ** kwargs )
@@ -703,7 +703,14 @@ def _new_chat_completion_common(f: "Any", *args: "Any", **kwargs: "Any") -> "Any
703703 _set_completions_api_input_data (span , kwargs , integration )
704704
705705 start_time = time .perf_counter ()
706- response = yield f , args , kwargs
706+
707+ try :
708+ response = f (* args , ** kwargs )
709+ except Exception as exc :
710+ exc_info = sys .exc_info ()
711+ with capture_internal_exceptions ():
712+ _capture_exception (exc )
713+ reraise (* exc_info )
707714
708715 # Attribute check to fail gracefully if the attribute is not present in future `openai` versions.
709716 if isinstance (response , Stream ) and hasattr (response , "_iterator" ):
@@ -722,8 +729,58 @@ def _new_chat_completion_common(f: "Any", *args: "Any", **kwargs: "Any") -> "Any
722729 finish_span = True ,
723730 )
724731
732+ else :
733+ _set_completions_api_output_data (
734+ span , response , kwargs , integration , finish_span = True
735+ )
736+
737+ return response
738+
739+
740+ async def _new_async_chat_completion (f : "Any" , * args : "Any" , ** kwargs : "Any" ) -> "Any" :
741+ integration = sentry_sdk .get_client ().get_integration (OpenAIIntegration )
742+ if integration is None :
743+ return await f (* args , ** kwargs )
744+
745+ if "messages" not in kwargs :
746+ # invalid call (in all versions of openai), let it return error
747+ return await f (* args , ** kwargs )
748+
749+ try :
750+ iter (kwargs ["messages" ])
751+ except TypeError :
752+ # invalid call (in all versions), messages must be iterable
753+ return await f (* args , ** kwargs )
754+
755+ model = kwargs .get ("model" )
756+
757+ span = sentry_sdk .start_span (
758+ op = consts .OP .GEN_AI_CHAT ,
759+ name = f"chat { model } " ,
760+ origin = OpenAIIntegration .origin ,
761+ )
762+ span .__enter__ ()
763+
764+ span .set_data (SPANDATA .GEN_AI_SYSTEM , "openai" )
765+
766+ # Same bool handling as in https://github.com/openai/openai-python/blob/acd0c54d8a68efeedde0e5b4e6c310eef1ce7867/src/openai/resources/completions.py#L585
767+ is_streaming_response = kwargs .get ("stream" , False ) or False
768+ span .set_data (SPANDATA .GEN_AI_RESPONSE_STREAMING , is_streaming_response )
769+
770+ _set_completions_api_input_data (span , kwargs , integration )
771+
772+ start_time = time .perf_counter ()
773+
774+ try :
775+ response = await f (* args , ** kwargs )
776+ except Exception as exc :
777+ exc_info = sys .exc_info ()
778+ with capture_internal_exceptions ():
779+ _capture_exception (exc )
780+ reraise (* exc_info )
781+
725782 # Attribute check to fail gracefully if the attribute is not present in future `openai` versions.
726- elif isinstance (response , AsyncStream ) and hasattr (response , "_iterator" ):
783+ if isinstance (response , AsyncStream ) and hasattr (response , "_iterator" ):
727784 messages = kwargs .get ("messages" )
728785
729786 if messages is not None and isinstance (messages , str ):
@@ -1060,69 +1117,27 @@ def _set_embeddings_output_data(
10601117
10611118
10621119def _wrap_chat_completion_create (f : "Callable[..., Any]" ) -> "Callable[..., Any]" :
1063- def _execute_sync (f : "Any" , * args : "Any" , ** kwargs : "Any" ) -> "Any" :
1064- gen = _new_chat_completion_common (f , * args , ** kwargs )
1065-
1066- try :
1067- f , args , kwargs = next (gen )
1068- except StopIteration as e :
1069- return e .value
1070-
1071- try :
1072- try :
1073- result = f (* args , ** kwargs )
1074- except Exception as e :
1075- exc_info = sys .exc_info ()
1076- with capture_internal_exceptions ():
1077- _capture_exception (e )
1078- reraise (* exc_info )
1079-
1080- return gen .send (result )
1081- except StopIteration as e :
1082- return e .value
1083-
10841120 @wraps (f )
10851121 def _sentry_patched_create_sync (* args : "Any" , ** kwargs : "Any" ) -> "Any" :
10861122 integration = sentry_sdk .get_client ().get_integration (OpenAIIntegration )
10871123 if integration is None or "messages" not in kwargs :
10881124 # no "messages" means invalid call (in all versions of openai), let it return error
10891125 return f (* args , ** kwargs )
10901126
1091- return _execute_sync (f , * args , ** kwargs )
1127+ return _new_sync_chat_completion (f , * args , ** kwargs )
10921128
10931129 return _sentry_patched_create_sync
10941130
10951131
10961132def _wrap_async_chat_completion_create (f : "Callable[..., Any]" ) -> "Callable[..., Any]" :
1097- async def _execute_async (f : "Any" , * args : "Any" , ** kwargs : "Any" ) -> "Any" :
1098- gen = _new_chat_completion_common (f , * args , ** kwargs )
1099-
1100- try :
1101- f , args , kwargs = next (gen )
1102- except StopIteration as e :
1103- return await e .value
1104-
1105- try :
1106- try :
1107- result = await f (* args , ** kwargs )
1108- except Exception as e :
1109- exc_info = sys .exc_info ()
1110- with capture_internal_exceptions ():
1111- _capture_exception (e )
1112- reraise (* exc_info )
1113-
1114- return gen .send (result )
1115- except StopIteration as e :
1116- return e .value
1117-
11181133 @wraps (f )
11191134 async def _sentry_patched_create_async (* args : "Any" , ** kwargs : "Any" ) -> "Any" :
11201135 integration = sentry_sdk .get_client ().get_integration (OpenAIIntegration )
11211136 if integration is None or "messages" not in kwargs :
11221137 # no "messages" means invalid call (in all versions of openai), let it return error
11231138 return await f (* args , ** kwargs )
11241139
1125- return await _execute_async (f , * args , ** kwargs )
1140+ return await _new_async_chat_completion (f , * args , ** kwargs )
11261141
11271142 return _sentry_patched_create_async
11281143
0 commit comments