Open-source LLM observability and evaluation platform. Python SDK provides tracing via @observe decorator, OpenTelemetry integration, and a low-level client for manual trace/span management. Works with any LLM framework — not tied to LangChain. Self-hostable (Docker/Kubernetes) or cloud (EU/US regions). MAJOR VERSION NOTE: SDK was completely rewritten in v3 (released June 2025). v3 is OpenTelemetry-based with a new singleton client pattern. All v2 import paths, class names, and initialization patterns are broken in v3. pip install langfuse installs v3 as of Feb 2026.
Install & Compatibility
Where this runs
tested against v4.7.1 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
py 3.10
8/10 runs
8/10 runs
py 3.11
8/10 runs
8/10 runs
py 3.12
8/10 runs
8/10 runs
py 3.13
8/10 runs
8/10 runs
Code
Verified usage
Verified import paths — ran on the pinned version, not inferred.
Langfuse / get_client (v3)
✓ from langfuse import Langfuse, get_client
✗ from langfuse import Langfuse as LangfuseClient
In v3, Langfuse() initializes the singleton. get_client() retrieves it anywhere in the codebase. The v2 pattern of creating a new Langfuse() per request is now wrong.
@observe decorator (v3)
✓ from langfuse.decorators import observe
✗ from langfuse import observe
v3 decorator import path. Top-level from langfuse import observe does not exist in v3.
CallbackHandler for LangChain (v3)
✓ from langfuse.langchain import CallbackHandler
✗ from langfuse.callback import CallbackHandler
v2 used langfuse.callback. v3 uses langfuse.langchain. Both the import path and initialization changed.
Langfuse() must be called once at startup to initialize the singleton. get_client() retrieves it anywhere. In v3, the client is NOT created per-request. Always call langfuse.flush() before script exit or in shutdown hooks.
import os
os.environ['LANGFUSE_SECRET_KEY'] = 'sk-lf-...'
os.environ['LANGFUSE_PUBLIC_KEY'] = 'pk-lf-...'
os.environ['LANGFUSE_BASE_URL'] = 'https://cloud.langfuse.com' # EU
from langfuse import Langfuse, get_client
from langfuse.decorators import observe
# Initialize singleton once at startup
Langfuse()
# Verify connection
langfuse = get_client()
if langfuse.auth_check():
print('Connected!')
# @observe traces any function
@observe()
def my_llm_call(prompt: str) -> str:
import openai
client = openai.OpenAI()
response = client.chat.completions.create(
model='gpt-4o',
messages=[{'role': 'user', 'content': prompt}]
)
return response.choices[0].message.content
result = my_llm_call('Hello!')
# Flush traces before exit in short-lived scripts
langfuse.flush()
# LangChain integration (v3 import path)
from langfuse.langchain import CallbackHandler
handler = CallbackHandler()
# Pass handler to chain: chain.invoke({...}, config={'callbacks': [handler]})
langfuse --version
Debug
Known issues
breakingSDK v3 (June 2025) is a complete rewrite. v2 import paths, class names, and initialization patterns all changed. The most critical breaks: (1) Langfuse() is now a singleton initializer, not a per-request client. (2) from langfuse.callback import CallbackHandler → from langfuse.langchain import CallbackHandler. (3) @observe import moved. pip install langfuse now installs v3.fixFollow the official v3 migration guide at langfuse.com/docs/sdk/python/sdk-v3. Pin langfuse<3 if not ready to migrate.
affects: >=3.0.0
breakingSelf-hosted Langfuse: Python SDK v3 requires Langfuse platform version ≥ 3.125.0. Running SDK v3 against a self-hosted platform older than 3.125.0 causes silent failures or API errors.fixUpgrade self-hosted platform to ≥ 3.125.0 before upgrading the Python SDK to v3. Or pin langfuse<3 until the platform is updated.
affects: >=3.0.0 (self-hosted)
breakingLANGFUSE_BASE_URL has no universal default. EU and US cloud use different endpoints. Not setting this env var causes all API calls to fail — often with a connection timeout rather than a clear auth error.fixAlways set LANGFUSE_BASE_URL explicitly. EU: https://cloud.langfuse.com. US: https://us.cloud.langfuse.com. Self-hosted: your instance URL.
affects: all
gotchaTraces are sent asynchronously. In short-lived scripts (CLI tools, batch jobs, test suites), the process exits before traces flush, resulting in missing data in the UI with no error.fixCall langfuse.flush() at the end of scripts or register it in an atexit handler. In pytest, use the langfuse pytest fixture or add flush() to teardown.
affects: all
gotchaThere is a separate stub package 'langfuse-sdk' on PyPI (version 1.0.0) that is NOT the current SDK — it's an old redirect stub that predates the rename. pip install langfuse-sdk installs an abandoned package.fixAlways install 'langfuse' (not 'langfuse-sdk'): pip install langfuse.
affects: all
Errors
Common errors & fixes
ModuleNotFoundError: No module named 'langfuse.langchain'
The import path for LangChain's `CallbackHandler` changed significantly in Langfuse Python SDK v3. This error typically occurs when using an older v2 import pattern with a v3 installation or vice versa.
fixFor Langfuse SDK v3, import the `CallbackHandler` from `langfuse.langchain`. Ensure `langfuse` version 3.x is installed (e.g., `pip install 'langfuse>=3.0.0'`).
```python
# Correct for Langfuse v3
from langfuse.langchain import CallbackHandler
```
ModuleNotFoundError: No module named 'langfuse.decorators'
In Langfuse Python SDK v3, the `observe` decorator's import path was moved directly into the `langfuse` package from the deprecated `langfuse.decorators` module.
fixImport the `observe` decorator directly from the `langfuse` package.
```python
# Correct for Langfuse v3
from langfuse import observe
@observe()
def my_function():
pass
``` AttributeError: 'Langfuse' object has no attribute 'trace'
The direct `.trace()` method on the `Langfuse` client object was removed in SDK v3. Tracing is now managed through the `@observe` decorator or explicit OpenTelemetry context managers.
fixInstead of `langfuse.trace(...)`, use the `@observe` decorator for functions or `langfuse.start_as_current_span()` (preferably with a `with` statement) for manual span management.
```python
# Correct for Langfuse v3 using decorator
from langfuse import observe
@observe(name="my-trace-name")
def my_traced_function():
pass
# Correct for Langfuse v3 using context manager
from langfuse import get_client
langfuse = get_client()
with langfuse.start_as_current_span(name="my-span") as span:
span.update(input="some_input")
``` TypeError: Langfuse.__init__() got an unexpected keyword argument 'sdk_integration'
The `Langfuse` client constructor was refactored in SDK v3, removing certain keyword arguments like `sdk_integration` that were present in v2. This indicates an attempt to initialize the v3 client using v2 configuration parameters.
fixRemove deprecated arguments like `sdk_integration` from the `Langfuse` constructor. Initialize the client with valid v3 arguments, such as `public_key`, `secret_key`, `host`, `debug`, or `tracing_enabled`. The recommended approach is often to use `get_client()` which relies on environment variables.
```python
# Incorrect (v2 pattern)
# langfuse = Langfuse(sdk_integration="my-app")
# Correct for Langfuse v3
from langfuse import Langfuse, get_client
# Option 1: Initialize with environment variables (recommended)
langfuse_client = get_client()
# Option 2: Initialize with constructor arguments
langfuse_client = Langfuse(
public_key="pk-lf-...",
secret_key="sk-lf-...",
host="https://cloud.langfuse.com"
)
``` AttributeError: 'NoneType' object has no attribute 'start_as_current_span'
This error occurs in Langfuse SDK v3 when the internal OpenTelemetry tracer is `None`, which can happen if the `Langfuse` client fails to initialize correctly. Common reasons include missing `LANGFUSE_PUBLIC_KEY` or `LANGFUSE_SECRET_KEY` environment variables, or specific ways of attempting to disable tracing that leave the tracer uninitialized.
fixEnsure that `LANGFUSE_PUBLIC_KEY` and `LANGFUSE_SECRET_KEY` are set as environment variables or passed directly to the `Langfuse` client constructor. If you intend to disable tracing, ensure it's done correctly, typically by setting `tracing_enabled=False` during client initialization, or by setting `LANGFUSE_TRACING_ENABLED=false` or `OTEL_SDK_DISABLED=true` environment variables, while still providing dummy keys if needed for initialization.
```python
import os
from langfuse import Langfuse
# Ensure environment variables are set:
# os.environ["LANGFUSE_PUBLIC_KEY"] = "pk-lf-..."
# os.environ["LANGFUSE_SECRET_KEY"] = "sk-lf-..."
# os.environ["LANGFUSE_BASE_URL"] = "https://cloud.langfuse.com"
# Or pass them directly:
langfuse = Langfuse(
public_key=os.getenv("LANGFUSE_PUBLIC_KEY", "dummy-public-key"),
secret_key=os.getenv("LANGFUSE_SECRET_KEY", "dummy-secret-key"),
host=os.getenv("LANGFUSE_BASE_URL", "http://localhost:3000"),
# If tracing is explicitly disabled, ensure keys are still provided for proper initialization
# tracing_enabled=False
)
``` Audit
Dependencies
No dependency data recorded yet.