Tracing With The langfuse
Python SDK
Application Tracing
Python
Using the LangFuse Python SDK for Detailed Tracing
Problem: You need precise control over your traces, spans, and metadata while maintaining the reliability and features of the official LangFuse Python SDK.
Solution: Use the LangFuse Python SDK’s decorator-based tracing with the @observe
decorator. This approach provides excellent control over trace structure while benefiting from automatic retries, error handling, and SDK features.
When to Use This Approach
Use the LangFuse Python SDK when:
- ✅ Production applications - Need reliable trace delivery with retries
- ✅ Complex workflows - Require nested spans and detailed metadata
- ✅ Team collaboration - Want standardized tracing patterns
- ✅ Maintenance - Benefit from SDK updates and improvements
- ✅ Development speed - Focus on application logic, not HTTP details
Complete Example: Decorator-Based Tracing
Here’s a complete example that creates both trace and span data using the LangFuse Python SDK with the @observe
decorator:
from getpass import getuser
import time
import uuid
from dotenv import dotenv_values
from langfuse import Langfuse, observe
# Load environment variables
= dotenv_values()
secrets
# Initialize LangFuse client
= Langfuse(
langfuse =secrets["PUBLIC_KEY"],
public_key=secrets["SECRET_KEY"],
secret_key=secrets["LANGFUSE_HOST"]
host
)
def main():
= str(uuid.uuid4())
session_id = str(uuid.uuid4())
trace_id = str(uuid.uuid4())
span_id
= getuser()
username
print("--- Creating Trace ---")
print(f"✅ Trace ID: {trace_id}")
print(f"✅ Session ID: {session_id}")
print(f"✅ User: {username}")
# Step 1: Execute the function we want to trace
def translate_text():
= "Hello, world!"
input_text = "Bonjour le monde"
translated print("Translating:", input_text)
print("Translated:", translated)
return input_text, translated
# Start timing (same as test_requests.py)
= time.time()
start_time # Simulated task
= translate_text()
input_text, output_text = time.time()
end_time # measure latency
= int((end_time - start_time) * 1000)
duration_ms
print(f"\n--- Creating Span ---")
print(f"✅ Span ID: {span_id}")
print(f"✅ Duration: {duration_ms}ms")
@observe(name="manual-translate-trace")
def create_trace():
# Create a span within the trace
return create_translation_span(input_text, output_text, duration_ms, span_id)
@observe(name="translate-function")
def create_translation_span(input_text, output_text, duration_ms, span_id):
return {
"input": {"text": input_text},
"output": {"translated": output_text},
"duration_ms": duration_ms,
"span_id": span_id
}
# Execute the traced functions
create_trace()
print(f"✅ Trace created with span")
# Step 2: Ensure all data is sent
print("\n--- Flushing Data ---")
langfuse.flush()print("✅ All traces flushed to LangFuse")
return {
"trace_id": trace_id,
"span_id": span_id,
"session_id": session_id,
"result": output_text,
"duration_ms": duration_ms,
"user_id": username
}
if __name__ == "__main__":
= main()
result print(f"\n📊 Summary: {result}")
When to Use Raw HTTP Requests
Switch to raw HTTP requests when:
- You need to see exact HTTP status codes and error messages
- The SDK is hiding important debugging information
- You’re troubleshooting authentication or connectivity issues
- You need to understand the underlying API structure
What’s Next?
Now that you know the Python SDK fundamentals:
- Raw Requests - Use HTTP requests directly
- OpenTelemetry - Implement standardized tracing
- Azure Deployment - Deploy your own LangFuse instance
🎯 You’re ready to implement comprehensive SDK-based tracing!