litellm/tests/logging_callback_tests/test_langfuse_dynamic_credentials.py
Yuneng Jiang feffb62266
test: refresh the suites that drifted from langfuse and OpenAI's retired Assistants API
Two unrelated causes, both leaving staging red with tests that no longer describe
anything true.

#38264 gave LangFuseLogger a langfuse_environment argument and started carrying it
in the credentials dict. The handler test's fake logger did not accept the new
keyword, so constructing it raised TypeError, and four cases in
test_langfuse_unit_tests rebuilt the cache key by hand from three fields and missed
on the four-field key production now writes. Caching itself was never broken: the
handler sets and gets with the same dict. The fake now takes the argument and
asserts it is forwarded, and the cache assertion issues a second identical request
and expects the same logger back, which is the behaviour that matters and cannot
rot the next time a credential field is added.

OpenAI has retired the Assistants API. /v1/assistants and /v1/threads both answer
404 with a valid key, where every live route answers 401, so nothing calling them
can pass again. test_custom_logger_passthrough covered generic passthrough logging
and only used assistants because it is a route with no provider-specific handler;
it moves to /v1/moderations, which is still unclaimed by
_is_supported_openai_endpoint, so the same generic branch is exercised. The two
tests there asserted the same thing against different dead routes, so they collapse
into one. The Ruby suite existed solely to drive assistants, threads, messages and
runs, so it goes along with the RVM and bundler steps that were installed only to
run it, and the two dead OpenAI assistants cases leave
test_openai_assistants_passthrough.

The Azure assistants case in that file stays. Azure runs its own lifecycle and I
could not reach the CI deployment to check whether that API is still there.
2026-08-27 23:24:36 -07:00

133 lines
4.9 KiB
Python

import sys
from types import ModuleType, SimpleNamespace
import litellm
from litellm.integrations.langfuse.langfuse import resolve_langfuse_credentials
from litellm.integrations.langfuse.langfuse_handler import LangFuseHandler
def test_resolve_langfuse_credentials_does_not_use_env_for_dynamic_host(monkeypatch):
monkeypatch.setenv("LANGFUSE_PUBLIC_KEY", "global-public")
monkeypatch.setenv("LANGFUSE_SECRET_KEY", "global-secret")
public_key, secret_key, host = resolve_langfuse_credentials(
langfuse_host="https://attacker.example",
allow_env_credentials=False,
)
assert public_key is None
assert secret_key is None
assert host == "https://attacker.example"
def test_resolve_langfuse_credentials_accepts_secret_key_alias_for_dynamic_host(
monkeypatch,
):
monkeypatch.setenv("LANGFUSE_SECRET_KEY", "global-secret")
public_key, secret_key, host = resolve_langfuse_credentials(
langfuse_public_key="dynamic-public",
langfuse_secret_key="dynamic-secret",
langfuse_host="https://team-langfuse.example",
allow_env_credentials=False,
)
assert public_key == "dynamic-public"
assert secret_key == "dynamic-secret"
assert host == "https://team-langfuse.example"
def test_resolve_langfuse_credentials_keeps_env_for_global_config(monkeypatch):
monkeypatch.setenv("LANGFUSE_PUBLIC_KEY", "global-public")
monkeypatch.setenv("LANGFUSE_SECRET_KEY", "global-secret")
public_key, secret_key, host = resolve_langfuse_credentials(
langfuse_host="https://admin-configured.example",
allow_env_credentials=True,
)
assert public_key == "global-public"
assert secret_key == "global-secret"
assert host == "https://admin-configured.example"
def test_upstream_langfuse_debug_env_is_passed(monkeypatch):
from litellm.integrations.langfuse.langfuse import LangFuseLogger
class FakeLangfuse:
instances = []
def __init__(self, **kwargs):
self.kwargs = kwargs
FakeLangfuse.instances.append(self)
fake_langfuse_module = ModuleType("langfuse")
fake_langfuse_module.Langfuse = FakeLangfuse
fake_langfuse_module.version = SimpleNamespace(__version__="2.6.0")
monkeypatch.setitem(sys.modules, "langfuse", fake_langfuse_module)
monkeypatch.setattr(litellm, "initialized_langfuse_clients", 0)
monkeypatch.setenv("LANGFUSE_MOCK", "true")
monkeypatch.setenv("UPSTREAM_LANGFUSE_SECRET_KEY", "upstream-secret")
monkeypatch.setenv("UPSTREAM_LANGFUSE_PUBLIC_KEY", "upstream-public")
monkeypatch.setenv("UPSTREAM_LANGFUSE_HOST", "https://upstream.example")
monkeypatch.setenv("UPSTREAM_LANGFUSE_RELEASE", "release")
monkeypatch.setenv("UPSTREAM_LANGFUSE_DEBUG", "true")
logger = LangFuseLogger(
langfuse_public_key="public",
langfuse_secret="secret",
langfuse_host="https://langfuse.example",
)
assert logger.upstream_langfuse_debug == "true"
assert FakeLangfuse.instances[-1].kwargs["debug"] is True
def test_langfuse_handler_accepts_secret_key_alias(monkeypatch):
captured = {}
class FakeLangFuseLogger:
def __init__(
self,
*,
langfuse_public_key=None,
langfuse_secret=None,
langfuse_host=None,
langfuse_environment=None,
allow_env_credentials=True,
):
captured["langfuse_public_key"] = langfuse_public_key
captured["langfuse_secret"] = langfuse_secret
captured["langfuse_host"] = langfuse_host
captured["langfuse_environment"] = langfuse_environment
captured["allow_env_credentials"] = allow_env_credentials
class FakeDynamicLoggingCache:
def set_cache(self, *, credentials, service_name, logging_obj):
captured["cached_credentials"] = credentials
captured["cached_service_name"] = service_name
captured["cached_logging_obj"] = logging_obj
monkeypatch.setattr(
"litellm.integrations.langfuse.langfuse_handler.LangFuseLogger",
FakeLangFuseLogger,
)
logger = LangFuseHandler._create_langfuse_logger_from_credentials(
credentials={
"langfuse_public_key": "dynamic-public",
"langfuse_secret_key": "dynamic-secret",
"langfuse_host": "https://langfuse.example",
"langfuse_environment": "dynamic-environment",
},
in_memory_dynamic_logger_cache=FakeDynamicLoggingCache(),
)
assert captured["langfuse_public_key"] == "dynamic-public"
assert captured["langfuse_secret"] == "dynamic-secret"
assert captured["langfuse_host"] == "https://langfuse.example"
assert captured["langfuse_environment"] == "dynamic-environment"
assert captured["allow_env_credentials"] is False
assert captured["cached_service_name"] == "langfuse"
assert captured["cached_logging_obj"] is logger