Skip to content

deps: bump langfuse to v4 + migrate tracer/tests off v3 APIs#13277

Open
thesaadmirza wants to merge 6 commits into
langflow-ai:mainfrom
thesaadmirza:bump-langfuse-pin-for-python-314
Open

deps: bump langfuse to v4 + migrate tracer/tests off v3 APIs#13277
thesaadmirza wants to merge 6 commits into
langflow-ai:mainfrom
thesaadmirza:bump-langfuse-pin-for-python-314

Conversation

@thesaadmirza
Copy link
Copy Markdown

@thesaadmirza thesaadmirza commented May 22, 2026

Bug

src/backend/base/pyproject.toml (at v1.9.3 + main) pins:

langfuse = ["langfuse~=3.8; python_version < '3.14'"]

The environment marker means on Python 3.14 the langfuse SDK is not installed at all.

Reproduced against the published image:

$ docker run --rm langflowai/langflow:1.9.3 python3 --version
Python 3.14.5

$ docker run --rm langflowai/langflow:1.9.3 python3 -c 'import langfuse'
ModuleNotFoundError: No module named 'langfuse'

requires-python = ">=3.10,<3.15" and the published Dockerfile uses python:3.14-slim-trixie, so this is the default path. Setting LANGFUSE_* env vars on a default install produces "Could not import langfuse" on every flow run (langfuse.py:101).

Fix

Bump the pin to v4 AND migrate the tracer + tests off the v3 API. The first version of this PR only touched the pin — @coderabbitai correctly caught that the tracer code calls v3-only methods (client.start_span, span.update_trace) which don't exist on v4. Single-line pin bumps would break tracing at runtime; the full migration is below.

Pin change

- langfuse = ["langfuse~=3.8; python_version < '3.14'"]
+ langfuse = ["langfuse>=4,<5"]

Tracer migration (src/backend/base/langflow/services/tracing/langfuse.py)

v3 (before) v4 (after)
client.start_span(...) client.start_observation(...)
span.start_span(...) span.start_observation(...)
root.update_trace(name=, user_id=, session_id=) propagate_attributes(trace_name=, user_id=, session_id=) context manager, entered in _setup_langfuse, exited in end()
root.update_trace(input=, output=) root.set_trace_io(input=, output=)
span.update(...), span.end(), Langfuse.create_trace_id(...), CallbackHandler(trace_context=...) unchanged in v4

The propagate_attributes CM is the load-bearing piece — trace attributes are no longer span parameters, they propagate via OTel context. Manually entering and exiting (rather than wrapping the whole tracer lifecycle in a with block) keeps the procedural BaseTracer interface intact.

Test migration

tests/unit/services/tracing/test_langfuse_v3_compatibility.pytest_langfuse_v4_compatibility.py. Mocks updated to v4 surface (start_observation + a context-manager-shaped propagate_attributes). Removed v3-specific assertions (update_trace count, start_span calls); added v4 assertions (propagate_attributes invoked with trace_name/user_id/session_id, set_trace_io called in end(), start_observation on root + child).

Verification

All 12 tests pass against the real langfuse==4.6.1 inside langflowai/langflow:1.9.3:

$ docker run --rm \
    -v "$(pwd)/src/backend/base/langflow/services/tracing/langfuse.py:/app/.venv/lib/python3.14/site-packages/langflow/services/tracing/langfuse.py" \
    -v "$(pwd)/src/backend/tests/unit/services/tracing/test_langfuse_v4_compatibility.py:/tests/test_langfuse_v4_compatibility.py" \
    langflowai/langflow:1.9.3 bash -c '
      /app/.venv/bin/pip install --quiet "langfuse==4.6.1" pytest
      cd /tests && /app/.venv/bin/python -m pytest test_langfuse_v4_compatibility.py -v'

test_langfuse_client_has_start_observation       PASSED
test_langfuse_client_has_create_trace_id         PASSED
test_langfuse_module_has_propagate_attributes    PASSED
test_langfuse_client_does_not_have_v3_start_span PASSED
test_callback_handler_import_path                PASSED
test_tracer_initialization_does_not_crash        PASSED
test_tracer_uses_v4_api_for_initialization       PASSED
test_add_trace_creates_child_observation         PASSED
test_end_trace_updates_and_ends_span             PASSED
test_end_updates_root_span_and_set_trace_io      PASSED
test_get_langchain_callback_uses_trace_context   PASSED
test_get_langchain_callback_includes_parent_span_id  PASSED

12 passed in 6.74s

Plus a live-tracer round-trip (constructed tracer → add_traceget_langchain_callbackend_traceend → all v4 calls executed, OTel context entered/exited cleanly).

Why v4

  • langfuse 4.6.1 (released 2026-05-08) supports Python 3.10–3.14. See langfuse discussion #11409.
  • v3 (~=3.8) depends on pydantic v1 internals incompatible with Python 3.14 (the spike that prompted the python_version < '3.14' marker in the first place — see PR #11216 precedent for v2→v3).

Note on langwatch

Two lines below the langfuse pin, langwatch~=0.10.0; python_version < '3.14' has the same bug pattern. Out of scope for this PR; flagged here in case someone wants to file a follow-up.

Related

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 22, 2026

Important

Review skipped

Auto incremental reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 489588eb-1d7f-4b8e-91a3-ba5a0360e808

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Walkthrough

The PR updates the langfuse optional dependency in langflow-base from version 3.8 (restricted to Python <3.14) to version 4 (unrestricted), removing the Python version marker and changing the version constraint format.

Changes

Langfuse v4 compatibility

Layer / File(s) Summary
Langfuse v4 dependency update
src/backend/base/pyproject.toml
The langfuse optional dependency is updated from langfuse~=3.8; python_version < '3.14' to langfuse>=4,<5, removing the Python version restriction and upgrading to the next major version.

Estimated code review effort

🎯 1 (Trivial) | ⏱️ ~2 minutes


Important

Pre-merge checks failed

Please resolve all errors before merging. Addressing warnings is optional.

❌ Failed checks (1 error, 1 warning)

Check name Status Explanation Resolution
Test Coverage For New Implementations ❌ Error Langfuse bumped to v4 but code uses v3 APIs (start_span, update_trace) with no new tests for v4. No test coverage for breaking API changes in v4. Add v4 compatibility tests or update implementation to v4 APIs (start_observation, propagate_attributes). v3→v4 migration has breaking changes requiring code updates.
Test Quality And Coverage ⚠️ Warning Tests cover main functionality but lack comprehensive error scenario coverage. No tests for ImportError, auth failures, or ready=False edge cases that the code explicitly handles. Add tests for error scenarios: ImportError handling, auth_check failures, and operations when ready=False. Also test _get_config directly.
✅ Passed checks (7 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Test File Naming And Structure ✅ Passed Test file meets all requirements: test_*.py naming pattern, pytest structure with fixtures, 3 test classes, 12 descriptive test methods, setup/teardown, positive/negative scenarios, error handling.
Excessive Mock Usage Warning ✅ Passed Test file shows excessive mocking (6 of 12 tests mock entire langfuse SDK with 7+ MagicMock objects), but this pre-existing code is not changed by this PR's pyproject.toml dependency update.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately reflects the main change: bumping langfuse to v4 and migrating tracer/tests off v3 APIs, which addresses the Python 3.14 compatibility issue.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/backend/base/pyproject.toml`:
- Line 237: The pyproject was bumped to langfuse>=4 but
src/backend/base/langflow/services/tracing/langfuse.py and its tests are written
against the v3 API (LangFuseTracer class, imports of
langfuse._client.span.LangfuseSpan and langfuse.types.TraceContext, calls to
self._client.start_span, span.update_trace, span.update, Langfuse.start_span and
get_langchain_callback/CallbackHandler), so either pin the dependency to <4 or
migrate the tracer and tests to v4: update imports to v4 module paths, replace
start_span/start_generation usages with start_observation and the new
observation methods, switch trace attribute propagation to
propagate_attributes/observation-level APIs, adapt or remove CallbackHandler
usage per v4, and update
src/backend/tests/unit/services/tracing/test_langfuse_v3_compatibility.py to
validate the new v4 behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 3a2000a5-f5b3-4656-84a3-56d4b68ee14d

📥 Commits

Reviewing files that changed from the base of the PR and between 49de16c and 34f366a.

📒 Files selected for processing (1)
  • src/backend/base/pyproject.toml

Comment thread src/backend/base/pyproject.toml
Pin: langfuse~=3.8; python_version < 3.14  →  langfuse>=4,<5

The pyproject conditional silently skipped install on Python 3.14 (the
runtime in langflowai/langflow:1.9.3). v4.6.1 is pydantic-v2 / Python-3.14
compatible.

Tracer rewritten for v4 surface:
- client.start_span → client.start_observation
- span.start_span  → span.start_observation
- update_trace(name, user_id, session_id) → propagate_attributes(...)
  entered in _setup_langfuse, exited in end()
- update_trace(input, output) → set_trace_io(input, output)
- end()/update()/CallbackHandler signatures unchanged

Tests file renamed v3_compatibility → v4_compatibility; mocks updated to
v4 surface (start_observation + propagate_attributes context manager).
All 12 tests pass against langfuse 4.6.1 inside langflowai/langflow:1.9.3.
@thesaadmirza thesaadmirza force-pushed the bump-langfuse-pin-for-python-314 branch from 34f366a to b26f024 Compare May 22, 2026 09:18
@thesaadmirza thesaadmirza changed the title deps: bump langfuse pin to v4 — fixes missing install on Python 3.14 deps: bump langfuse to v4 + migrate tracer/tests off v3 APIs May 22, 2026
autofix-ci Bot and others added 4 commits May 22, 2026 09:21
propagate_attributes was held across the tracer's whole life, but child spans run in a worker task whose contextvars predate the token, so user.id/session.id never landed on them. Per-call wrap fixes it.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant