Skip to content

Commit d66d003

Browse files
committed
add deprecation warning
1 parent 1ce911f commit d66d003

3 files changed

Lines changed: 171 additions & 5 deletions

File tree

langfuse/_client/client.py

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
import logging
77
import os
8+
import warnings
89
import re
910
import urllib.parse
1011
from datetime import datetime
@@ -727,7 +728,10 @@ def start_generation(
727728
cost_details: Optional[Dict[str, float]] = None,
728729
prompt: Optional[PromptClient] = None,
729730
) -> LangfuseGeneration:
730-
"""Create a new generation span for model generations.
731+
"""[DEPRECATED] Create a new generation span for model generations.
732+
733+
DEPRECATED: This method is deprecated and will be removed in a future version.
734+
Use start_observation(as_type='generation') instead.
731735
732736
This method creates a specialized span for tracking model generations.
733737
It includes additional fields specific to model generations such as model name,
@@ -777,6 +781,12 @@ def start_generation(
777781
generation.end()
778782
```
779783
"""
784+
warnings.warn(
785+
"start_generation is deprecated and will be removed in a future version. "
786+
"Use start_observation(as_type='generation') instead.",
787+
DeprecationWarning,
788+
stacklevel=2,
789+
)
780790
return self.start_observation(
781791
trace_context=trace_context,
782792
name=name,
@@ -814,7 +824,10 @@ def start_as_current_generation(
814824
prompt: Optional[PromptClient] = None,
815825
end_on_exit: Optional[bool] = None,
816826
) -> _AgnosticContextManager[LangfuseGeneration]:
817-
"""Create a new generation span and set it as the current span in a context manager.
827+
"""[DEPRECATED] Create a new generation span and set it as the current span in a context manager.
828+
829+
DEPRECATED: This method is deprecated and will be removed in a future version.
830+
Use start_as_current_observation(as_type='generation') instead.
818831
819832
This method creates a specialized span for model generations and sets it as the
820833
current span within a context manager. Use this method with a 'with' statement to
@@ -862,6 +875,12 @@ def start_as_current_generation(
862875
)
863876
```
864877
"""
878+
warnings.warn(
879+
"start_as_current_generation is deprecated and will be removed in a future version. "
880+
"Use start_as_current_observation(as_type='generation') instead.",
881+
DeprecationWarning,
882+
stacklevel=2,
883+
)
865884
return self.start_as_current_observation(
866885
trace_context=trace_context,
867886
name=name,

langfuse/_client/span.py

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
from datetime import datetime
1717
from time import time_ns
18+
import warnings
1819
from typing import (
1920
TYPE_CHECKING,
2021
Any,
@@ -1176,7 +1177,10 @@ def start_as_current_span(
11761177
level: Optional[SpanLevel] = None,
11771178
status_message: Optional[str] = None,
11781179
) -> _AgnosticContextManager["LangfuseSpan"]:
1179-
"""Create a new child span and set it as the current span in a context manager.
1180+
"""[DEPRECATED] Create a new child span and set it as the current span in a context manager.
1181+
1182+
DEPRECATED: This method is deprecated and will be removed in a future version.
1183+
Use start_as_current_observation(as_type='span') instead.
11801184
11811185
This method creates a new child span and sets it as the current span within
11821186
a context manager. It should be used with a 'with' statement to automatically
@@ -1210,6 +1214,12 @@ def start_as_current_span(
12101214
parent_span.update(output=result)
12111215
```
12121216
"""
1217+
warnings.warn(
1218+
"start_as_current_span is deprecated and will be removed in a future version. "
1219+
"Use start_as_current_observation(as_type='span') instead.",
1220+
DeprecationWarning,
1221+
stacklevel=2,
1222+
)
12131223
return self.start_as_current_observation(
12141224
name=name,
12151225
as_type="span",
@@ -1238,7 +1248,10 @@ def start_generation(
12381248
cost_details: Optional[Dict[str, float]] = None,
12391249
prompt: Optional[PromptClient] = None,
12401250
) -> "LangfuseGeneration":
1241-
"""Create a new child generation span.
1251+
"""[DEPRECATED] Create a new child generation span.
1252+
1253+
DEPRECATED: This method is deprecated and will be removed in a future version.
1254+
Use start_observation(as_type='generation') instead.
12421255
12431256
This method creates a new child generation span with this span as the parent.
12441257
Generation spans are specialized for AI/LLM operations and include additional
@@ -1295,6 +1308,12 @@ def start_generation(
12951308
span.end()
12961309
```
12971310
"""
1311+
warnings.warn(
1312+
"start_generation is deprecated and will be removed in a future version. "
1313+
"Use start_observation(as_type='generation') instead.",
1314+
DeprecationWarning,
1315+
stacklevel=2,
1316+
)
12981317
return self.start_observation(
12991318
name=name,
13001319
as_type="generation",
@@ -1329,7 +1348,10 @@ def start_as_current_generation(
13291348
cost_details: Optional[Dict[str, float]] = None,
13301349
prompt: Optional[PromptClient] = None,
13311350
) -> _AgnosticContextManager["LangfuseGeneration"]:
1332-
"""Create a new child generation span and set it as the current span in a context manager.
1351+
"""[DEPRECATED] Create a new child generation span and set it as the current span in a context manager.
1352+
1353+
DEPRECATED: This method is deprecated and will be removed in a future version.
1354+
Use start_as_current_observation(as_type='generation') instead.
13331355
13341356
This method creates a new child generation span and sets it as the current span
13351357
within a context manager. Generation spans are specialized for AI/LLM operations
@@ -1381,6 +1403,12 @@ def start_as_current_generation(
13811403
span.update(output={"answer": response.text, "source": "gpt-4"})
13821404
```
13831405
"""
1406+
warnings.warn(
1407+
"start_as_current_generation is deprecated and will be removed in a future version. "
1408+
"Use start_as_current_observation(as_type='generation') instead.",
1409+
DeprecationWarning,
1410+
stacklevel=2,
1411+
)
13841412
return cast(
13851413
_AgnosticContextManager["LangfuseGeneration"],
13861414
self.start_as_current_observation(

tests/test_deprecation.py

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
"""Tests for deprecation warnings on deprecated functions."""
2+
3+
import warnings
4+
import pytest
5+
from unittest.mock import patch
6+
7+
from langfuse import Langfuse
8+
9+
10+
class TestDeprecationWarnings:
11+
"""Test that deprecated functions emit proper deprecation warnings."""
12+
13+
# List of deprecated functions and their expected warning messages. Target is the object they are called on.
14+
DEPRECATED_FUNCTIONS = [
15+
# on the client:
16+
{
17+
"method": "start_generation",
18+
"target": "client",
19+
"kwargs": {"name": "test_generation"},
20+
"expected_message": "start_generation is deprecated and will be removed in a future version. Use start_observation(as_type='generation') instead.",
21+
},
22+
{
23+
"method": "start_as_current_generation",
24+
"target": "client",
25+
"kwargs": {"name": "test_generation"},
26+
"expected_message": "start_as_current_generation is deprecated and will be removed in a future version. Use start_as_current_observation(as_type='generation') instead.",
27+
},
28+
# on the span:
29+
{
30+
"method": "start_generation",
31+
"target": "span",
32+
"kwargs": {"name": "test_generation"},
33+
"expected_message": "start_generation is deprecated and will be removed in a future version. Use start_observation(as_type='generation') instead.",
34+
},
35+
{
36+
"method": "start_as_current_generation",
37+
"target": "span",
38+
"kwargs": {"name": "test_generation"},
39+
"expected_message": "start_as_current_generation is deprecated and will be removed in a future version. Use start_as_current_observation(as_type='generation') instead.",
40+
},
41+
{
42+
"method": "start_as_current_span",
43+
"target": "span",
44+
"kwargs": {"name": "test_span"},
45+
"expected_message": "start_as_current_span is deprecated and will be removed in a future version. Use start_as_current_observation(as_type='span') instead.",
46+
},
47+
]
48+
49+
@pytest.fixture
50+
def langfuse_client(self):
51+
"""Create a Langfuse client for testing."""
52+
with patch.dict(
53+
"os.environ",
54+
{
55+
"LANGFUSE_PUBLIC_KEY": "test_key",
56+
"LANGFUSE_SECRET_KEY": "test_secret",
57+
"LANGFUSE_HOST": "http://localhost:3000",
58+
},
59+
):
60+
return Langfuse()
61+
62+
@pytest.mark.parametrize("func_info", DEPRECATED_FUNCTIONS)
63+
def test_deprecated_function_warnings(self, langfuse_client, func_info):
64+
"""Test that deprecated functions emit proper deprecation warnings."""
65+
method_name = func_info["method"]
66+
target = func_info["target"]
67+
kwargs = func_info["kwargs"]
68+
expected_message = func_info["expected_message"]
69+
70+
with warnings.catch_warnings(record=True) as warning_list:
71+
warnings.simplefilter("always")
72+
73+
try:
74+
if target == "client":
75+
# Test deprecated methods on the client
76+
method = getattr(langfuse_client, method_name)
77+
if "current" in method_name:
78+
# Context manager methods
79+
with method(**kwargs) as obj:
80+
if hasattr(obj, "end"):
81+
obj.end()
82+
else:
83+
# Regular methods
84+
obj = method(**kwargs)
85+
if hasattr(obj, "end"):
86+
obj.end()
87+
88+
elif target == "span":
89+
# Test deprecated methods on spans
90+
span = langfuse_client.start_span(name="test_parent")
91+
method = getattr(span, method_name)
92+
if "current" in method_name:
93+
# Context manager methods
94+
with method(**kwargs) as obj:
95+
if hasattr(obj, "end"):
96+
obj.end()
97+
else:
98+
# Regular methods
99+
obj = method(**kwargs)
100+
if hasattr(obj, "end"):
101+
obj.end()
102+
span.end()
103+
104+
except Exception:
105+
pass
106+
107+
# Check that a deprecation warning was emitted
108+
deprecation_warnings = [
109+
w for w in warning_list if issubclass(w.category, DeprecationWarning)
110+
]
111+
assert (
112+
len(deprecation_warnings) > 0
113+
), f"No DeprecationWarning emitted for {target}.{method_name}"
114+
115+
# Check that the warning message matches expected
116+
warning_messages = [str(w.message) for w in deprecation_warnings]
117+
assert (
118+
expected_message in warning_messages
119+
), f"Expected warning message not found for {target}.{method_name}. Got: {warning_messages}"

0 commit comments

Comments
 (0)