From e1f359c62177ca27a4a749e241e8200a4ed55322 Mon Sep 17 00:00:00 2001 From: Vedant-2-6 Date: Mon, 31 Aug 2026 19:39:43 +0530 Subject: [PATCH] feat: upgrade Langfuse integration to SDK v4 and add deprecation warning Addresses #33383, as requested by the Langfuse team. Changes: 1. pyproject.toml: Bump langfuse dependency from >=2.59.7,<3.0 to >=4.7,<5 in both proxy-runtime and dev dependency groups. The v4 ingestion path (Langfuse Cloud Fast Preview) requires SDK 4.7+. 2. litellm/integrations/langfuse/langfuse.py: Add DeprecationWarning to LangFuseLogger.__init__ directing users to LangfuseOtelLogger (the langfuse_otel callback). The OTel callback already carries the required x-langfuse-ingestion-version: 4 header via _build_langfuse_otel_headers and is the recommended path for Langfuse v4 Cloud Fast Preview. Note: langfuse_otel.py already implements the v4 ingestion header correctly via LANGFUSE_INGESTION_VERSION_HEADER / LANGFUSE_INGESTION_VERSION constants and _build_langfuse_otel_headers; no changes are needed there. --- litellm/integrations/langfuse/langfuse.py | 11 +++++++++++ pyproject.toml | 6 +++--- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/litellm/integrations/langfuse/langfuse.py b/litellm/integrations/langfuse/langfuse.py index 296c2b5714e..f940af2a2ff 100644 --- a/litellm/integrations/langfuse/langfuse.py +++ b/litellm/integrations/langfuse/langfuse.py @@ -166,6 +166,17 @@ class LangFuseLogger: raise Exception( f"\033[91mLangfuse not installed, try running 'pip install langfuse' to fix this error: {e}\n{traceback.format_exc()}\033[0m" ) + import warnings + + warnings.warn( + "LangFuseLogger (the 'langfuse' callback) uses the Langfuse Python SDK " + "and is deprecated in favour of LangfuseOtelLogger (the 'langfuse_otel' " + "callback), which sends spans directly over OpenTelemetry and is compatible " + "with Langfuse v4 Cloud Fast Preview. " + "Set success_callback=['langfuse_otel'] to switch to the new integration.", + DeprecationWarning, + stacklevel=2, + ) self.public_key, self.secret_key, self.langfuse_host = resolve_langfuse_credentials( langfuse_public_key=langfuse_public_key, langfuse_secret=langfuse_secret, diff --git a/pyproject.toml b/pyproject.toml index 34c1fec1c11..19e74db45ec 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -146,7 +146,7 @@ proxy-runtime = [ "anthropic[vertex]>=0.84.0,<1.0", "grpcio==1.78.0", "prometheus-client>=0.20.0,<1.0", - "langfuse>=2.59.7,<3.0", + "langfuse>=4.7,<5", "opentelemetry-api==1.28.0", "opentelemetry-sdk==1.28.0", "opentelemetry-exporter-otlp==1.28.0", @@ -195,7 +195,7 @@ dev = [ "opentelemetry-sdk==1.28.0", "opentelemetry-exporter-otlp==1.28.0", "opentelemetry-instrumentation-fastapi==0.49b0", - "langfuse==2.59.7", + "langfuse>=4.7,<5", "fastapi-offline==1.7.6", "fakeredis==2.34.1", "pytest-rerunfailures==15.1", @@ -356,7 +356,7 @@ also_copy = [ # Run the test suite once before mutation to gather line coverage, then skip # mutating lines no test exercises. Those mutants would survive regardless # (no test hits the line to kill them), so generating them wastes hours of CI. -# The score now reads as "mutation score over covered code" — pair with a +# The score now reads as "mutation score over covered code" — pair with a # line-coverage number when reporting. mutate_only_covered_lines = true # Disable rerun/parallel plugins for mutation runs: