1313and scoring integration specific to Langfuse's observability platform.
1414"""
1515
16- from abc import ABC , abstractmethod
1716from datetime import datetime
17+ from time import time_ns
1818from typing import (
1919 TYPE_CHECKING ,
2020 Any ,
4545from langfuse .types import MapValue , ScoreDataType , SpanLevel
4646
4747
48- class LangfuseSpanWrapper ( ABC ) :
48+ class LangfuseSpanWrapper :
4949 """Abstract base class for all Langfuse span types.
5050
5151 This class provides common functionality for all Langfuse span types, including
@@ -64,7 +64,7 @@ def __init__(
6464 * ,
6565 otel_span : otel_trace_api .Span ,
6666 langfuse_client : "Langfuse" ,
67- as_type : Literal ["span" , "generation" ],
67+ as_type : Literal ["span" , "generation" , "event" ],
6868 input : Optional [Any ] = None ,
6969 output : Optional [Any ] = None ,
7070 metadata : Optional [Any ] = None ,
@@ -133,18 +133,6 @@ def end(self, *, end_time: Optional[int] = None):
133133
134134 return self
135135
136- @abstractmethod
137- def update (self , ** kwargs ) -> Union ["LangfuseSpan" , "LangfuseGeneration" ]:
138- """Update the span with new information.
139-
140- Abstract method that must be implemented by subclasses to update
141- the span with new information during its lifecycle.
142-
143- Args:
144- **kwargs: Subclass-specific update parameters
145- """
146- pass
147-
148136 def update_trace (
149137 self ,
150138 * ,
@@ -352,7 +340,7 @@ def _set_processed_span_attributes(
352340 self ,
353341 * ,
354342 span : otel_trace_api .Span ,
355- as_type : Optional [Literal ["span" , "generation" ]] = None ,
343+ as_type : Optional [Literal ["span" , "generation" , "event" ]] = None ,
356344 input : Optional [Any ] = None ,
357345 output : Optional [Any ] = None ,
358346 metadata : Optional [Any ] = None ,
@@ -934,6 +922,69 @@ def start_as_current_generation(
934922 ),
935923 )
936924
925+ def create_event (
926+ self ,
927+ * ,
928+ name : str ,
929+ input : Optional [Any ] = None ,
930+ output : Optional [Any ] = None ,
931+ metadata : Optional [Any ] = None ,
932+ version : Optional [str ] = None ,
933+ level : Optional [SpanLevel ] = None ,
934+ status_message : Optional [str ] = None ,
935+ ) -> "LangfuseEvent" :
936+ """Create a new Langfuse observation of type 'EVENT'.
937+
938+ Args:
939+ name: Name of the span (e.g., function or operation name)
940+ input: Input data for the operation (can be any JSON-serializable object)
941+ output: Output data from the operation (can be any JSON-serializable object)
942+ metadata: Additional metadata to associate with the span
943+ version: Version identifier for the code or component
944+ level: Importance level of the span (info, warning, error)
945+ status_message: Optional status message for the span
946+
947+ Returns:
948+ The LangfuseEvent object
949+
950+ Example:
951+ ```python
952+ event = langfuse.create_event(name="process-event")
953+ ```
954+ """
955+ timestamp = time_ns ()
956+ attributes = create_span_attributes (
957+ input = input ,
958+ output = output ,
959+ metadata = metadata ,
960+ version = version ,
961+ level = level ,
962+ status_message = status_message ,
963+ )
964+
965+ with otel_trace_api .use_span (self ._otel_span ):
966+ new_otel_span = self ._langfuse_client ._otel_tracer .start_span (
967+ name = name , attributes = attributes , start_time = timestamp
968+ )
969+
970+ if new_otel_span .is_recording :
971+ self ._set_processed_span_attributes (
972+ span = new_otel_span ,
973+ as_type = "event" ,
974+ input = input ,
975+ output = output ,
976+ metadata = metadata ,
977+ )
978+
979+ return LangfuseEvent (
980+ otel_span = new_otel_span ,
981+ langfuse_client = self ._langfuse_client ,
982+ input = input ,
983+ output = output ,
984+ metadata = metadata ,
985+ environment = self ._environment ,
986+ ).end (end_time = timestamp )
987+
937988
938989class LangfuseGeneration (LangfuseSpanWrapper ):
939990 """Specialized span implementation for AI model generations in Langfuse.
@@ -1069,3 +1120,37 @@ def update(
10691120 self ._otel_span .set_attributes (attributes = attributes )
10701121
10711122 return self
1123+
1124+
1125+ class LangfuseEvent (LangfuseSpanWrapper ):
1126+ """Specialized span implementation for Langfuse Events."""
1127+
1128+ def __init__ (
1129+ self ,
1130+ * ,
1131+ otel_span : otel_trace_api .Span ,
1132+ langfuse_client : "Langfuse" ,
1133+ input : Optional [Any ] = None ,
1134+ output : Optional [Any ] = None ,
1135+ metadata : Optional [Any ] = None ,
1136+ environment : Optional [str ] = None ,
1137+ ):
1138+ """Initialize a new LangfuseEvent span.
1139+
1140+ Args:
1141+ otel_span: The OpenTelemetry span to wrap
1142+ langfuse_client: Reference to the parent Langfuse client
1143+ input: Input data for the generation (e.g., prompts)
1144+ output: Output from the generation (e.g., completions)
1145+ metadata: Additional metadata to associate with the generation
1146+ environment: The tracing environment
1147+ """
1148+ super ().__init__ (
1149+ otel_span = otel_span ,
1150+ as_type = "event" ,
1151+ langfuse_client = langfuse_client ,
1152+ input = input ,
1153+ output = output ,
1154+ metadata = metadata ,
1155+ environment = environment ,
1156+ )
0 commit comments