Make a Langfuse trace worth opening: question, answer, session, no probe noise
This commit is contained in:
@@ -120,3 +120,104 @@ def test_otel_server_and_stage_spans_share_trace_and_emit_metric_exemplar():
|
||||
assert "duocthu_stage_duration_seconds_bucket" in rendered
|
||||
assert 'trace_id="' in rendered
|
||||
import pytest
|
||||
|
||||
|
||||
def test_langfuse_exporter_added_only_when_fully_configured():
|
||||
"""Langfuse is opt-in: all three settings, or no extra exporter at all.
|
||||
|
||||
A half-configured Langfuse (say a base URL pasted in but no keys yet)
|
||||
must not produce an exporter that would fail auth on every batch.
|
||||
"""
|
||||
from rag.telemetry import _langfuse_exporters
|
||||
|
||||
captured = []
|
||||
|
||||
def fake_exporter(**kwargs):
|
||||
captured.append(kwargs)
|
||||
return object()
|
||||
|
||||
# Explicit empty values, not Settings() defaults: Settings reads the
|
||||
# developer's real .env, which on a configured machine already carries
|
||||
# live Langfuse keys and would make this assertion pass or fail by
|
||||
# accident depending on whose machine runs it.
|
||||
unset = Settings(
|
||||
langfuse_base_url="", langfuse_public_key="", langfuse_secret_key=""
|
||||
)
|
||||
assert _langfuse_exporters(unset, fake_exporter) == []
|
||||
assert (
|
||||
_langfuse_exporters(
|
||||
Settings(
|
||||
langfuse_base_url="https://langfuse.example",
|
||||
langfuse_public_key="",
|
||||
langfuse_secret_key="",
|
||||
),
|
||||
fake_exporter,
|
||||
)
|
||||
== []
|
||||
)
|
||||
assert captured == []
|
||||
|
||||
result = _langfuse_exporters(
|
||||
Settings(
|
||||
langfuse_base_url="https://langfuse.example/",
|
||||
langfuse_public_key="pk-lf-public",
|
||||
langfuse_secret_key="sk-lf-secret",
|
||||
),
|
||||
fake_exporter,
|
||||
)
|
||||
|
||||
assert len(result) == 1
|
||||
assert len(captured) == 1
|
||||
# Trailing slash stripped, so the path is not doubled.
|
||||
assert captured[0]["endpoint"] == "https://langfuse.example/api/public/otel/v1/traces"
|
||||
# Basic auth is public-key-as-username, secret-key-as-password.
|
||||
import base64
|
||||
|
||||
expected = base64.b64encode(b"pk-lf-public:sk-lf-secret").decode()
|
||||
assert captured[0]["headers"] == {"Authorization": f"Basic {expected}"}
|
||||
|
||||
|
||||
def test_langfuse_score_client_is_all_or_nothing():
|
||||
"""Same partial-config rule as the span exporter, for the same reason."""
|
||||
from adapters.langfuse_scores import LangfuseScoreClient
|
||||
|
||||
unset = Settings(
|
||||
langfuse_base_url="", langfuse_public_key="", langfuse_secret_key=""
|
||||
)
|
||||
assert LangfuseScoreClient.from_settings(unset) is None
|
||||
assert (
|
||||
LangfuseScoreClient.from_settings(
|
||||
Settings(
|
||||
langfuse_base_url="https://langfuse.example",
|
||||
langfuse_public_key="pk-lf-x",
|
||||
langfuse_secret_key="",
|
||||
)
|
||||
)
|
||||
is None
|
||||
)
|
||||
|
||||
client = LangfuseScoreClient.from_settings(
|
||||
Settings(
|
||||
langfuse_base_url="https://langfuse.example/",
|
||||
langfuse_public_key="pk-lf-public",
|
||||
langfuse_secret_key="sk-lf-secret",
|
||||
)
|
||||
)
|
||||
assert client is not None
|
||||
# Trailing slash stripped, so the path is not doubled.
|
||||
assert client.endpoint == "https://langfuse.example/api/public/scores"
|
||||
|
||||
|
||||
def test_langfuse_score_post_never_raises(monkeypatch):
|
||||
"""A Langfuse outage must not propagate into the feedback request path."""
|
||||
from adapters import langfuse_scores
|
||||
|
||||
client = langfuse_scores.LangfuseScoreClient(
|
||||
"https://langfuse.example", "pk", "sk"
|
||||
)
|
||||
|
||||
def boom(*args, **kwargs):
|
||||
raise OSError("connection refused")
|
||||
|
||||
monkeypatch.setattr(langfuse_scores.urllib.request, "urlopen", boom)
|
||||
assert client.post_score(otel_trace_id="a" * 32, name="user_feedback", value=1.0) is False
|
||||
|
||||
Reference in New Issue
Block a user