1- """Langfuse integration service using v3 SDK.
1+ """Langfuse integration service using v2 SDK.
22
3- Clean implementation without backwards compatibility wrappers.
3+ Provides v3-style method aliases (start_span, start_generation) on top of
4+ the v2 API so callers can use either naming convention.
45"""
56
67from langfuse import Langfuse
@@ -25,39 +26,80 @@ def update(self, **_kwargs) -> "MockObservation":
2526 def end (self , ** kwargs ) -> None :
2627 pass
2728
29+ def span (self , name : str = "" , ** _kwargs ) -> "MockObservation" :
30+ return MockObservation ()
31+
2832 def start_span (self , name : str = "" , ** _kwargs ) -> "MockObservation" :
2933 return MockObservation ()
3034
35+ def generation (self , name : str = "" , ** _kwargs ) -> "MockObservation" :
36+ return MockObservation ()
37+
3138 def start_generation (self , name : str = "" , ** _kwargs ) -> "MockObservation" :
3239 return MockObservation ()
3340
34- def event (self , name : str , ** kwargs ) -> None :
41+ def event (self , name : str = "" , ** kwargs ) -> None :
3542 """Log an event (no-op for mock)."""
3643
3744
45+ class TraceWrapper :
46+ """Wraps a v2 StatefulTraceClient to add v3-style aliases."""
47+
48+ def __init__ (self , trace ):
49+ self ._trace = trace
50+
51+ def span (self , name : str = "" , ** kwargs ):
52+ return self ._trace .span (name = name , ** kwargs )
53+
54+ def start_span (self , name : str = "" , ** kwargs ):
55+ """v3-style alias for span()."""
56+ return self ._trace .span (name = name , ** kwargs )
57+
58+ def generation (self , name : str = "" , ** kwargs ):
59+ return self ._trace .generation (name = name , ** kwargs )
60+
61+ def start_generation (self , name : str = "" , ** kwargs ):
62+ """v3-style alias for generation()."""
63+ return self ._trace .generation (name = name , ** kwargs )
64+
65+ def update (self , ** kwargs ):
66+ return self ._trace .update (** kwargs )
67+
68+ def end (self , ** kwargs ):
69+ if hasattr (self ._trace , "end" ):
70+ return self ._trace .end (** kwargs )
71+
72+ def event (self , name : str = "" , ** kwargs ):
73+ if hasattr (self ._trace , "event" ):
74+ return self ._trace .event (name = name , ** kwargs )
75+
76+ def __getattr__ (self , name ):
77+ return getattr (self ._trace , name )
78+
79+
3880# Initialize Langfuse client
3981langfuse : Langfuse | None = None
4082
4183try :
4284 if enabled :
4385 langfuse = Langfuse (public_key = public_key , secret_key = secret_key , host = host )
44- logger .info ("Langfuse v3 initialized successfully (enabled=True)" )
86+ logger .info ("Langfuse initialized successfully (enabled=True)" )
4587 else :
46- logger .info ("Langfuse v3 disabled (no credentials)" )
88+ logger .info ("Langfuse disabled (no credentials)" )
4789except Exception as e :
4890 logger .warning (f"Failed to initialize Langfuse: { e !s} " )
4991 langfuse = None
5092
5193
5294def log_event (trace , name : str , ** kwargs ) -> None :
53- """Log an event to a trace as a short-lived span (v3 pattern) .
95+ """Log an event to a trace as a short-lived span.
5496
55- In Langfuse v3, events are represented as spans that are immediately ended.
97+ Creates a span that is immediately ended.
5698 """
5799 if trace is None :
58100 return
59101 try :
60- span = trace .start_span (name = name )
102+ span = trace .span (name = name )
61103 update_kwargs = {}
62104 if "level" in kwargs :
63105 update_kwargs ["level" ] = kwargs ["level" ]
@@ -77,32 +119,30 @@ def log_event(trace, name: str, **kwargs) -> None:
77119
78120
79121def safe_trace (name : str , ** kwargs ):
80- """Create a Langfuse trace/span with error handling.
122+ """Create a Langfuse trace with error handling.
81123
82- Returns the root span observation object that supports :
83- - .start_span(name, **kwargs ) -> child span
84- - .start_generation(name, model, **kwargs ) -> generation
124+ Returns a TraceWrapper that supports both v2 and v3 method names :
125+ - .span() / .start_span( ) -> child span
126+ - .generation() / .start_generation( ) -> generation
85127 - .update(**kwargs) -> update observation
86128 - .end(**kwargs) -> end observation
87129 """
88130 try :
89131 if langfuse and enabled :
90- # Create root span
91- span_kwargs = {"name" : name }
132+ trace_kwargs = {"name" : name }
92133
93- # Map common trace parameters
94134 if "session_id" in kwargs :
95- span_kwargs ["session_id" ] = kwargs ["session_id" ]
135+ trace_kwargs ["session_id" ] = kwargs ["session_id" ]
96136 if "user_id" in kwargs :
97- span_kwargs ["user_id" ] = kwargs ["user_id" ]
137+ trace_kwargs ["user_id" ] = kwargs ["user_id" ]
98138 if "metadata" in kwargs :
99- span_kwargs ["metadata" ] = kwargs ["metadata" ]
139+ trace_kwargs ["metadata" ] = kwargs ["metadata" ]
100140 if "input" in kwargs :
101- span_kwargs ["input" ] = kwargs ["input" ]
141+ trace_kwargs ["input" ] = kwargs ["input" ]
102142 if "tags" in kwargs :
103- span_kwargs ["tags" ] = kwargs ["tags" ]
143+ trace_kwargs ["tags" ] = kwargs ["tags" ]
104144
105- return langfuse .start_span (** span_kwargs )
145+ return TraceWrapper ( langfuse .trace (** trace_kwargs ) )
106146 return MockObservation ()
107147 except Exception as e :
108148 logger .warning (f"Failed to create Langfuse trace '{ name } ': { e !s} " )
0 commit comments