← Back to changelog
May 23, 2025 | Launch Week 3 🚀

OTEL-based Python SDK

Picture Hassieb PakzadHassieb Pakzad

The latest generation of the Langfuse Python SDK, built on the OpenTelemetry framework.

On Day 5 of our Launch Week #3, we’re introducing the Langfuse Python SDK v3 (OpenTelemetry-based) in beta.

This is a significant update to our Python SDK as it is now built on the OpenTelemetry (OTEL) standard and designed to improve developer experience and enhance integration capabilities for tracing your LLM applications.

Key Improvement: OpenTelemetry Integration

The foundation of the v3 SDK is OpenTelemetry, which brings several practical advantages:

  • Standardized Context Propagation: OTEL automatically handles the propagation of trace and span context. This means when you create a new span or generation, it correctly nests under the currently active operation.
  • Third-Party Library Compatibility: Libraries already instrumented with OpenTelemetry will integrate with the Langfuse SDK, with their spans being captured and correctly nested within your Langfuse traces.

Simplified Tracing and Global Client Access

The new SDK aims to make tracing more straightforward. Here’s an example of how tracing can be implemented across different modules, leveraging automatic context propagation and global client access:

# main_app.py
from langfuse import get_client, observe
import other_module
 
# If no client is initialized, it will be initialized with the default configuration
# from the environment variables
langfuse = get_client()
 
@observe(name="user-request-pipeline")
def handle_user_request(user_query: str, user_id: str):
    # This span is now active. Enrich the trace with user info.
    langfuse.update_current_trace(user_id=user_id, tags=["experimental"])
 
    # Call a function from another module
    processed_data = other_module.process_data(user_query)
 
    # Update the root span
    langfuse.update_current_span(output={"final_result": processed_data})
    return processed_data
 
handle_user_request("Tell me a joke about OpenTelemetry", "user_123")
# other_module.py
from langfuse import get_client, observe
 
# Access the initialized Langfuse client globally
# If no client is initialized, it will be initialized with the default configuration
# from the environment variables
langfuse_client = get_client()
 
@observe(name="data-processing-step")
def process_data(query: str):
    # This span is automatically a child of "user-request-pipeline".
 
    with langfuse_client.start_as_current_generation(
        name="joke-generation-llm",
        model="gpt-4o",
        input=[{"role": "user", "content": query}]
    ) as generation:
        # Simulate LLM call
        joke = "Why did the OpenTelemetry collector break up with the span? It needed more space for its attributes!"
        generation.update(output=joke, usage_details={"input_tokens": 10, "output_tokens": 25})
 
    return joke

In this example:

  • Langfuse is initialized once.
  • The @observe decorator creates spans for handle_user_request and process_data.
  • other_module.py accesses the same client instance via get_client().
  • Spans are automatically nested due to OTEL’s context propagation.
  • Trace and span updates can be done contextually.

Seamless third-party integrations

The Langfuse SDK seamlessly integrates with any third-party library that uses OpenTelemetry instrumentation. When these libraries emit spans, they are automatically captured and properly nested within your trace hierarchy. This enables unified tracing across your entire application stack without requiring any additional configuration.

For example, if you’re using OpenTelemetry-instrumented databases, HTTP clients, or other services alongside your LLM operations, all these spans will be correctly organized within your traces in Langfuse.

You can use any third-party, OTEL-based instrumentation library for Anthropic to automatically trace all your Anthropic API calls in Langfuse.

In this example, we are using the opentelemetry-instrumentation-anthropic library.

from anthropic import Anthropic
from opentelemetry.instrumentation.anthropic import AnthropicInstrumentor
 
from langfuse import get_client
 
# This will automatically emit OTEL-spans for all Anthropic API calls
AnthropicInstrumentor().instrument()
 
langfuse = get_client()
anthropic_client = Anthropic()
 
with langfuse.start_as_current_span(name="myspan"):
    # This will be traced as a Langfuse generation nested under the current span
    message = anthropic_client.messages.create(
        model="claude-3-7-sonnet-20250219",
        max_tokens=1024,
        messages=[{"role": "user", "content": "Hello, Claude"}],
    )
 
    print(message.content)
 
# Flush events to Langfuse in short-lived applications
langfuse.flush()

Key Changes and Improvements:

  • Context Management: OpenTelemetry now handles context propagation automatically, reducing the need to manually pass IDs.
  • API for Observations:
    • Traces are implicitly created by the first (root) span or generation.
    • Use langfuse.start_as_current_span() or langfuse.start_as_current_generation() with context managers for automatic lifecycle management.
    • Manual creation via langfuse.start_span() or langfuse.start_generation() requires an explicit .end() call.
    • The name parameter is now required when creating spans and generations.
  • Observation IDs: Trace and Observation (Span) IDs adhere to the W3C Trace Context format. Use langfuse.create_trace_id() for generating IDs, including deterministic ones using a seed.
  • Updating Observations:
    • Use the .update() method on LangfuseSpan or LangfuseGeneration objects.
    • Update the currently active observation via langfuse.update_current_span() or langfuse.update_current_generation().
    • Update trace-level attributes via span_obj.update_trace() or langfuse.update_current_trace().
  • Integrations (OpenAI, Langchain): Trace-level attributes (like user_id, session_id) are now managed by creating an enclosing Langfuse span around the integrated library calls.
  • LlamaIndex: There is no longer a Langfuse-specific LlamaIndex integration; use third-party OTEL-based instrumentations.

We encourage you to try the new Python SDK v3 beta and welcome your feedback on GitHub.

Learn more

Was this page useful?

Questions? We're here to help

Subscribe to updates