← Back to changelog
June 5, 2025

Python SDK v3 is now Generally Available

Picture Hassieb PakzadHassieb Pakzad

The OpenTelemetry-based Python SDK v3 is now stable and ready for production use.

Following extensive testing and community feedback, we’re excited to announce that Langfuse Python SDK v3 is now generally available and ready for production use.

This major release brings the power of OpenTelemetry (OTEL) to LLM observability, providing a more robust and standards-compliant foundation for tracing your AI applications.

What’s new?

OpenTelemetry Foundation

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 resources are initialized once under the hood by the get_client() function. It can be accessed globally via langfuse = get_client().
  • 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

  • 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