mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-29 01:42:19 +00:00
fix: revert langfuse dep bump and add DeprecationWarning test
The langfuse>=4.7 dep bump caused an unsatisfiable dependency resolution: langfuse>=4.7 requires opentelemetry-sdk>=1.33.1, but litellm pins opentelemetry-sdk==1.28.0. The dep change is not needed because: - langfuse_otel (the recommended callback) sends spans via pure OTLP and imports zero langfuse SDK symbols - The legacy langfuse callback (being deprecated) continues to work with the existing langfuse>=2.59.7,<3.0 pin Also adds test_langfuse_legacy_callback_emits_deprecation_warning to tests/test_service_logger_otel.py to cover the new DeprecationWarning added to LangFuseLogger.__init__ in the previous commit.
This commit is contained in:
parent
e1f359c621
commit
d58d1d5554
2 changed files with 50 additions and 17 deletions
|
|
@ -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>=4.7,<5",
|
||||
"langfuse>=2.59.7,<3.0",
|
||||
"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>=4.7,<5",
|
||||
"langfuse==2.59.7",
|
||||
"fastapi-offline==1.7.6",
|
||||
"fakeredis==2.34.1",
|
||||
"pytest-rerunfailures==15.1",
|
||||
|
|
|
|||
|
|
@ -25,9 +25,7 @@ class TestServiceLoggerOTEL(unittest.IsolatedAsyncioTestCase):
|
|||
@patch("litellm.integrations.opentelemetry.OpenTelemetry._init_tracing")
|
||||
@patch("litellm.integrations.opentelemetry.OpenTelemetry._init_metrics")
|
||||
@patch("litellm.integrations.opentelemetry.OpenTelemetry._init_logs")
|
||||
async def test_langfuse_otel_ignores_service_logs(
|
||||
self, mock_logs, mock_metrics, mock_tracing
|
||||
):
|
||||
async def test_langfuse_otel_ignores_service_logs(self, mock_logs, mock_metrics, mock_tracing):
|
||||
"""
|
||||
Test that LangfuseOtelLogger overrides the service logging hooks with 'pass'.
|
||||
"""
|
||||
|
|
@ -46,9 +44,7 @@ class TestServiceLoggerOTEL(unittest.IsolatedAsyncioTestCase):
|
|||
@patch("litellm.integrations.opentelemetry.OpenTelemetry._init_tracing")
|
||||
@patch("litellm.integrations.opentelemetry.OpenTelemetry._init_metrics")
|
||||
@patch("litellm.integrations.opentelemetry.OpenTelemetry._init_logs")
|
||||
async def test_langfuse_otel_does_not_create_proxy_request_span(
|
||||
self, mock_logs, mock_metrics, mock_tracing
|
||||
):
|
||||
async def test_langfuse_otel_does_not_create_proxy_request_span(self, mock_logs, mock_metrics, mock_tracing):
|
||||
"""
|
||||
Test that LangfuseOtelLogger returns None for create_litellm_proxy_request_started_span.
|
||||
|
||||
|
|
@ -73,9 +69,7 @@ class TestServiceLoggerOTEL(unittest.IsolatedAsyncioTestCase):
|
|||
@patch("litellm.integrations.opentelemetry.OpenTelemetry._init_tracing")
|
||||
@patch("litellm.integrations.opentelemetry.OpenTelemetry._init_metrics")
|
||||
@patch("litellm.integrations.opentelemetry.OpenTelemetry._init_logs")
|
||||
async def test_service_logging_shadowing_fix(
|
||||
self, mock_logs, mock_metrics, mock_tracing
|
||||
):
|
||||
async def test_service_logging_shadowing_fix(self, mock_logs, mock_metrics, mock_tracing):
|
||||
"""
|
||||
Test the architectural fix: multiple OTEL loggers should receive logs independently.
|
||||
"""
|
||||
|
|
@ -89,9 +83,7 @@ class TestServiceLoggerOTEL(unittest.IsolatedAsyncioTestCase):
|
|||
service_logging = ServiceLogging()
|
||||
|
||||
# 3. Mock the base OpenTelemetry hook
|
||||
with patch.object(
|
||||
OpenTelemetry, "async_service_success_hook", new_callable=AsyncMock
|
||||
) as mock_base_hook:
|
||||
with patch.object(OpenTelemetry, "async_service_success_hook", new_callable=AsyncMock) as mock_base_hook:
|
||||
# Trigger a service event
|
||||
await service_logging.async_service_success_hook(
|
||||
service=ServiceTypes.DB,
|
||||
|
|
@ -112,9 +104,7 @@ class TestServiceLoggerOTEL(unittest.IsolatedAsyncioTestCase):
|
|||
@patch("litellm.integrations.opentelemetry.OpenTelemetry._init_tracing")
|
||||
@patch("litellm.integrations.opentelemetry.OpenTelemetry._init_metrics")
|
||||
@patch("litellm.integrations.opentelemetry.OpenTelemetry._init_logs")
|
||||
async def test_langfuse_otel_env_config_includes_v4_ingestion_header(
|
||||
self, mock_logs, mock_metrics, mock_tracing
|
||||
):
|
||||
async def test_langfuse_otel_env_config_includes_v4_ingestion_header(self, mock_logs, mock_metrics, mock_tracing):
|
||||
logger = LangfuseOtelLogger()
|
||||
|
||||
headers = OpenTelemetry._get_headers_dictionary(logger.config.headers)
|
||||
|
|
@ -147,6 +137,49 @@ class TestServiceLoggerOTEL(unittest.IsolatedAsyncioTestCase):
|
|||
)
|
||||
self.assertTrue(headers["Authorization"].startswith("Basic "))
|
||||
|
||||
def test_langfuse_legacy_callback_emits_deprecation_warning(self):
|
||||
"""
|
||||
Test that instantiating LangFuseLogger emits a DeprecationWarning
|
||||
directing users to switch to the langfuse_otel callback.
|
||||
"""
|
||||
import warnings
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
||||
mock_langfuse_module = MagicMock()
|
||||
mock_langfuse_module.Langfuse = MagicMock()
|
||||
|
||||
with patch.dict(
|
||||
"sys.modules",
|
||||
{
|
||||
"langfuse": mock_langfuse_module,
|
||||
"langfuse.client": MagicMock(),
|
||||
},
|
||||
):
|
||||
with warnings.catch_warnings(record=True) as caught:
|
||||
warnings.simplefilter("always")
|
||||
from litellm.integrations.langfuse.langfuse import LangFuseLogger
|
||||
|
||||
with patch(
|
||||
"litellm.integrations.langfuse.langfuse.resolve_langfuse_credentials",
|
||||
return_value=("pk", "sk", "https://cloud.langfuse.com"),
|
||||
):
|
||||
LangFuseLogger(
|
||||
langfuse_public_key="pk",
|
||||
langfuse_secret="sk",
|
||||
langfuse_host="https://cloud.langfuse.com",
|
||||
allow_env_credentials=False,
|
||||
)
|
||||
|
||||
deprecation_warnings = [w for w in caught if issubclass(w.category, DeprecationWarning)]
|
||||
self.assertTrue(
|
||||
len(deprecation_warnings) >= 1,
|
||||
"Expected at least one DeprecationWarning to be emitted",
|
||||
)
|
||||
self.assertIn(
|
||||
"langfuse_otel",
|
||||
str(deprecation_warnings[0].message),
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue