{"id":34,"library":"langfuse","title":"Langfuse","description":"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.","status":"active","version":"3.14.5","language":"python","source_language":"en","source_url":"https://github.com/langfuse/langfuse-python","tags":["langfuse","tracing","observability","llm-monitoring","opentelemetry","evaluation","self-hosted","open-source"],"install":[{"cmd":"pip install langfuse","lang":"bash","label":"Installs v3 (current)"},{"cmd":"pip install 'langfuse<3'","lang":"bash","label":"Pin to v2 if migrating gradually"}],"dependencies":[],"imports":[{"note":"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.","wrong":"from langfuse import Langfuse as LangfuseClient","symbol":"Langfuse / get_client (v3)","correct":"from langfuse import Langfuse, get_client"},{"note":"v3 decorator import path. Top-level from langfuse import observe does not exist in v3.","wrong":"from langfuse import observe","symbol":"@observe decorator (v3)","correct":"from langfuse.decorators import observe"},{"note":"v2 used langfuse.callback. v3 uses langfuse.langchain. Both the import path and initialization changed.","wrong":"from langfuse.callback import CallbackHandler","symbol":"CallbackHandler for LangChain (v3)","correct":"from langfuse.langchain import CallbackHandler"}],"quickstart":{"code":"import os\nos.environ['LANGFUSE_SECRET_KEY'] = 'sk-lf-...'\nos.environ['LANGFUSE_PUBLIC_KEY'] = 'pk-lf-...'\nos.environ['LANGFUSE_BASE_URL'] = 'https://cloud.langfuse.com'  # EU\n\nfrom langfuse import Langfuse, get_client\nfrom langfuse.decorators import observe\n\n# Initialize singleton once at startup\nLangfuse()\n\n# Verify connection\nlangfuse = get_client()\nif langfuse.auth_check():\n    print('Connected!')\n\n# @observe traces any function\n@observe()\ndef my_llm_call(prompt: str) -> str:\n    import openai\n    client = openai.OpenAI()\n    response = client.chat.completions.create(\n        model='gpt-4o',\n        messages=[{'role': 'user', 'content': prompt}]\n    )\n    return response.choices[0].message.content\n\nresult = my_llm_call('Hello!')\n\n# Flush traces before exit in short-lived scripts\nlangfuse.flush()\n\n# LangChain integration (v3 import path)\nfrom langfuse.langchain import CallbackHandler\nhandler = CallbackHandler()\n# Pass handler to chain: chain.invoke({...}, config={'callbacks': [handler]})","lang":"python","description":"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."},"warnings":[{"fix":"Follow the official v3 migration guide at langfuse.com/docs/sdk/python/sdk-v3. Pin langfuse<3 if not ready to migrate.","message":"SDK 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.","severity":"breaking","affected_versions":">=3.0.0"},{"fix":"Upgrade self-hosted platform to ≥ 3.125.0 before upgrading the Python SDK to v3. Or pin langfuse<3 until the platform is updated.","message":"Self-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.","severity":"breaking","affected_versions":">=3.0.0 (self-hosted)"},{"fix":"Always set LANGFUSE_BASE_URL explicitly. EU: https://cloud.langfuse.com. US: https://us.cloud.langfuse.com. Self-hosted: your instance URL.","message":"LANGFUSE_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.","severity":"breaking","affected_versions":"all"},{"fix":"Call 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.","message":"Traces 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.","severity":"gotcha","affected_versions":"all"},{"fix":"Always install 'langfuse' (not 'langfuse-sdk'): pip install langfuse.","message":"There 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.","severity":"gotcha","affected_versions":"all"}],"env_vars":{"required":[{"name":"LANGFUSE_SECRET_KEY","note":"Format: sk-lf-... Found in Langfuse project settings."},{"name":"LANGFUSE_PUBLIC_KEY","note":"Format: pk-lf-... Found in Langfuse project settings."},{"name":"LANGFUSE_BASE_URL","note":"EU cloud: https://cloud.langfuse.com | US cloud: https://us.cloud.langfuse.com | Self-hosted: your endpoint. Must be set explicitly — there is no default that works for all regions."}]},"last_verified":"2026-05-12T05:15:02.212Z","next_check":"2026-05-28T00:00:00.000Z","problems":[{"fix":"For Langfuse SDK v3, import the `CallbackHandler` from `langfuse.langchain`. Ensure `langfuse` version 3.x is installed (e.g., `pip install 'langfuse>=3.0.0'`).\n\n```python\n# Correct for Langfuse v3\nfrom langfuse.langchain import CallbackHandler\n```","cause":"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.","error":"ModuleNotFoundError: No module named 'langfuse.langchain'"},{"fix":"Import the `observe` decorator directly from the `langfuse` package.\n\n```python\n# Correct for Langfuse v3\nfrom langfuse import observe\n\n@observe()\ndef my_function():\n    pass\n```","cause":"In Langfuse Python SDK v3, the `observe` decorator's import path was moved directly into the `langfuse` package from the deprecated `langfuse.decorators` module.","error":"ModuleNotFoundError: No module named 'langfuse.decorators'"},{"fix":"Instead of `langfuse.trace(...)`, use the `@observe` decorator for functions or `langfuse.start_as_current_span()` (preferably with a `with` statement) for manual span management.\n\n```python\n# Correct for Langfuse v3 using decorator\nfrom langfuse import observe\n\n@observe(name=\"my-trace-name\")\ndef my_traced_function():\n    pass\n\n# Correct for Langfuse v3 using context manager\nfrom langfuse import get_client\n\nlangfuse = get_client()\nwith langfuse.start_as_current_span(name=\"my-span\") as span:\n    span.update(input=\"some_input\")\n```","cause":"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.","error":"AttributeError: 'Langfuse' object has no attribute 'trace'"},{"fix":"Remove 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.\n\n```python\n# Incorrect (v2 pattern)\n# langfuse = Langfuse(sdk_integration=\"my-app\")\n\n# Correct for Langfuse v3\nfrom langfuse import Langfuse, get_client\n\n# Option 1: Initialize with environment variables (recommended)\nlangfuse_client = get_client()\n\n# Option 2: Initialize with constructor arguments\nlangfuse_client = Langfuse(\n    public_key=\"pk-lf-...\",\n    secret_key=\"sk-lf-...\",\n    host=\"https://cloud.langfuse.com\"\n)\n```","cause":"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.","error":"TypeError: Langfuse.__init__() got an unexpected keyword argument 'sdk_integration'"},{"fix":"Ensure 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.\n\n```python\nimport os\nfrom langfuse import Langfuse\n\n# Ensure environment variables are set:\n# os.environ[\"LANGFUSE_PUBLIC_KEY\"] = \"pk-lf-...\"\n# os.environ[\"LANGFUSE_SECRET_KEY\"] = \"sk-lf-...\"\n# os.environ[\"LANGFUSE_BASE_URL\"] = \"https://cloud.langfuse.com\"\n\n# Or pass them directly:\nlangfuse = Langfuse(\n    public_key=os.getenv(\"LANGFUSE_PUBLIC_KEY\", \"dummy-public-key\"),\n    secret_key=os.getenv(\"LANGFUSE_SECRET_KEY\", \"dummy-secret-key\"),\n    host=os.getenv(\"LANGFUSE_BASE_URL\", \"http://localhost:3000\"),\n    # If tracing is explicitly disabled, ensure keys are still provided for proper initialization\n    # tracing_enabled=False \n)\n```","cause":"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.","error":"AttributeError: 'NoneType' object has no attribute 'start_as_current_span'"}],"ecosystem":"pypi","meta_description":null,"install_score":100,"install_tag":"verified","quickstart_score":0,"quickstart_tag":"stale","pypi_latest":null,"install_checks":{"last_tested":"2026-05-12","tag":"verified","tag_description":"installs cleanly on critical runtimes, fast import, recently tested","results":[{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":"default","exit_code":1,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":1.71,"mem_mb":25.8,"disk_size":"49.6M"},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":"default","exit_code":1,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":1.1,"mem_mb":24.5,"disk_size":"50M"},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":"default","exit_code":1,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":2.46,"mem_mb":28.2,"disk_size":"54.6M"},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":"default","exit_code":1,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":1.71,"mem_mb":26.9,"disk_size":"55M"},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":"default","exit_code":1,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":2.34,"mem_mb":27.7,"disk_size":"45.8M"},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":"default","exit_code":1,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":1.93,"mem_mb":26.5,"disk_size":"46M"},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":"default","exit_code":1,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":2.25,"mem_mb":28.3,"disk_size":"45.4M"},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":"default","exit_code":1,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":1.9,"mem_mb":27,"disk_size":"45M"},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":"default","exit_code":1,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":1.96,"mem_mb":28.9,"disk_size":"47.0M"},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":"default","exit_code":1,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":1.72,"mem_mb":27.5,"disk_size":"47M"}]},"quickstart_checks":{"last_tested":"2026-05-12","tag":"stale","tag_description":"widespread failures or data too old to trust","results":[{"runtime":"python:3.10-alpine","exit_code":1},{"runtime":"python:3.10-slim","exit_code":1},{"runtime":"python:3.11-alpine","exit_code":1},{"runtime":"python:3.11-slim","exit_code":1},{"runtime":"python:3.12-alpine","exit_code":1},{"runtime":"python:3.12-slim","exit_code":1},{"runtime":"python:3.13-alpine","exit_code":1},{"runtime":"python:3.13-slim","exit_code":1},{"runtime":"python:3.9-alpine","exit_code":1},{"runtime":"python:3.9-slim","exit_code":1}]}}