diff --git a/langfuse/openai.py b/langfuse/openai.py index 16e7f1c1f..d3758ecb5 100644 --- a/langfuse/openai.py +++ b/langfuse/openai.py @@ -80,24 +80,6 @@ class OpenAiDefinition: max_version: Optional[str] = None -OPENAI_METHODS_V0 = [ - OpenAiDefinition( - module="openai", - object="ChatCompletion", - method="create", - type="chat", - sync=True, - ), - OpenAiDefinition( - module="openai", - object="Completion", - method="create", - type="completion", - sync=True, - ), -] - - OPENAI_METHODS_V1 = [ OpenAiDefinition( module="openai.resources.chat.completions", @@ -798,8 +780,7 @@ def _extract_streamed_openai_response(resource: Any, chunks: Any) -> Any: model, usage, finish_reason, service_tier = None, None, None, None for chunk in chunks: - if _is_openai_v1(): - chunk = chunk.__dict__ + chunk = chunk.__dict__ model = model or chunk.get("model", None) or None service_tier = service_tier or chunk.get("service_tier", None) or None @@ -810,15 +791,14 @@ def _extract_streamed_openai_response(resource: Any, chunks: Any) -> Any: choices = chunk.get("choices") or [] for choice in choices: - if _is_openai_v1(): - choice = choice.__dict__ + choice = choice.__dict__ if resource.type == "chat": delta = choice.get("delta", None) choice_finish_reason = choice.get("finish_reason", None) if choice_finish_reason is not None: finish_reason = choice_finish_reason - if _is_openai_v1() and delta is not None: + if delta is not None: delta = delta.__dict__ if delta is None: @@ -956,7 +936,7 @@ def _get_langfuse_data_from_default_response( if len(choices) > 0: choice = choices[-1] - completion = choice.text if _is_openai_v1() else choice.get("text", None) + completion = choice.text elif resource.object == "Responses" or resource.object == "AsyncResponses": completion = _extract_response_api_completion(response.get("output", {})) @@ -968,17 +948,11 @@ def _get_langfuse_data_from_default_response( if len(choices) > 1: completion = [ _extract_chat_response(choice.message.__dict__) - if _is_openai_v1() - else choice.get("message", None) for choice in choices ] else: choice = choices[0] - completion = ( - _extract_chat_response(choice.message.__dict__) - if _is_openai_v1() - else choice.get("message", None) - ) + completion = _extract_chat_response(choice.message.__dict__) elif resource.type == "embedding": data = response.get("data") or [] @@ -1015,16 +989,12 @@ def _merge_service_tier_into_model_parameters( return {**(model_parameters or {}), "service_tier": service_tier} -def _is_openai_v1() -> bool: - return Version(openai.__version__) >= Version("1.0.0") - - def _is_streaming_response(response: Any) -> bool: return ( isinstance(response, types.GeneratorType) or isinstance(response, types.AsyncGeneratorType) - or (_is_openai_v1() and isinstance(response, openai.Stream)) - or (_is_openai_v1() and isinstance(response, openai.AsyncStream)) + or isinstance(response, openai.Stream) + or isinstance(response, openai.AsyncStream) ) @@ -1034,9 +1004,6 @@ def _is_streaming_response(response: Any) -> bool: def _install_openai_stream_iteration_hooks() -> None: global _openai_stream_iter_hook_installed - if not _is_openai_v1(): - return - if not _openai_stream_iter_hook_installed: original_iter = openai.Stream.__iter__ original_aiter = openai.AsyncStream.__aiter__ @@ -1318,7 +1285,7 @@ def _wrap( try: openai_response = wrapped(**arg_extractor.get_openai_args()) - if _is_openai_v1() and isinstance(openai_response, openai.Stream): + if isinstance(openai_response, openai.Stream): return _instrument_openai_stream( resource=open_ai_resource, response=openai_response, @@ -1338,9 +1305,7 @@ def _wrap( model, completion, usage, service_tier = ( _get_langfuse_data_from_default_response( open_ai_resource, - (parsed_response and parsed_response.__dict__) - if _is_openai_v1() - else parsed_response, + parsed_response and parsed_response.__dict__, ) ) @@ -1407,7 +1372,7 @@ async def _wrap_async( try: openai_response = await wrapped(**arg_extractor.get_openai_args()) - if _is_openai_v1() and isinstance(openai_response, openai.AsyncStream): + if isinstance(openai_response, openai.AsyncStream): return _instrument_openai_async_stream( resource=open_ai_resource, response=openai_response, @@ -1427,9 +1392,7 @@ async def _wrap_async( model, completion, usage, service_tier = ( _get_langfuse_data_from_default_response( open_ai_resource, - (parsed_response and parsed_response.__dict__) - if _is_openai_v1() - else parsed_response, + parsed_response and parsed_response.__dict__, ) ) generation.update( @@ -1460,9 +1423,7 @@ async def _wrap_async( def register_tracing() -> None: - resources = OPENAI_METHODS_V1 if _is_openai_v1() else OPENAI_METHODS_V0 - - for resource in resources: + for resource in OPENAI_METHODS_V1: if resource.min_version is not None and Version(openai.__version__) < Version( resource.min_version ): diff --git a/pyproject.toml b/pyproject.toml index 1534e4aa6..743bc32e6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -52,7 +52,7 @@ dev = [ "pytest-httpserver>=1.0.8,<2", "ruff>=0.15.2,<0.16", "mypy>=1.0.0,<2", - "openai>=0.27.8", + "openai>=1.0.0", "langchain-openai>=0.0.5,<0.4", "langchain>=1,<2", "langgraph>=1,<2", diff --git a/uv.lock b/uv.lock index ecacc3a0d..701ea859a 100644 --- a/uv.lock +++ b/uv.lock @@ -560,7 +560,7 @@ dev = [ { name = "langchain-openai", specifier = ">=0.0.5,<0.4" }, { name = "langgraph", specifier = ">=1,<2" }, { name = "mypy", specifier = ">=1.0.0,<2" }, - { name = "openai", specifier = ">=0.27.8" }, + { name = "openai", specifier = ">=1.0.0" }, { name = "opentelemetry-instrumentation-threading", specifier = ">=0.59b0,<1" }, { name = "pre-commit", specifier = ">=3.2.2,<4" }, { name = "pytest", specifier = ">=7.4,<9.0" },