From 8933f457fa06fa956273cfab17a7e0c215401a9f Mon Sep 17 00:00:00 2001 From: lorenzozanee Date: Tue, 11 Aug 2026 06:44:28 +0800 Subject: [PATCH] fix: treat empty-string credentials as missing and skip malformed media reference segments --- langfuse/_client/client.py | 4 ++-- langfuse/media.py | 2 ++ tests/unit/test_initialization.py | 21 +++++++++++++++++++++ tests/unit/test_media.py | 25 +++++++++++++++++++++++++ 4 files changed, 50 insertions(+), 2 deletions(-) diff --git a/langfuse/_client/client.py b/langfuse/_client/client.py index 2b2889545..6f8d0c9b6 100644 --- a/langfuse/_client/client.py +++ b/langfuse/_client/client.py @@ -379,7 +379,7 @@ def __init__( langfuse_logger.setLevel(logging.DEBUG) public_key = public_key or os.environ.get(LANGFUSE_PUBLIC_KEY) - if public_key is None: + if not public_key: langfuse_logger.warning( "Authentication error: Langfuse client initialized without public_key. Client will be disabled. " "Provide a public_key parameter or set LANGFUSE_PUBLIC_KEY environment variable. " @@ -388,7 +388,7 @@ def __init__( return secret_key = secret_key or os.environ.get(LANGFUSE_SECRET_KEY) - if secret_key is None: + if not secret_key: langfuse_logger.warning( "Authentication error: Langfuse client initialized without secret_key. Client will be disabled. " "Provide a secret_key parameter or set LANGFUSE_SECRET_KEY environment variable. " diff --git a/langfuse/media.py b/langfuse/media.py index d77de188d..1417b587f 100644 --- a/langfuse/media.py +++ b/langfuse/media.py @@ -253,6 +253,8 @@ def parse_reference_string(reference_string: str) -> ParsedMediaReference: parsed_data = {} for pair in pairs: + if "=" not in pair: + continue key, value = pair.split("=", 1) parsed_data[key] = value diff --git a/tests/unit/test_initialization.py b/tests/unit/test_initialization.py index 7181ae45e..c8b601a3c 100644 --- a/tests/unit/test_initialization.py +++ b/tests/unit/test_initialization.py @@ -7,6 +7,7 @@ import os import pytest +from opentelemetry.trace import NoOpTracer from langfuse import Langfuse from langfuse._client.resource_manager import LangfuseResourceManager @@ -313,3 +314,23 @@ def test_https_and_http_urls(self, cleanup_env_vars): secret_key="test_sk", ) assert client2._base_url == "http://insecure.com" + + def test_empty_public_key_env_disables_client(self, cleanup_env_vars, monkeypatch): + """Test that an empty LANGFUSE_PUBLIC_KEY env var disables the client.""" + monkeypatch.setenv("LANGFUSE_PUBLIC_KEY", "") + monkeypatch.setenv("LANGFUSE_SECRET_KEY", "sk-test") + + client = Langfuse() + + assert isinstance(client._otel_tracer, NoOpTracer) + assert client._resources is None + + def test_empty_secret_key_env_disables_client(self, cleanup_env_vars, monkeypatch): + """Test that an empty LANGFUSE_SECRET_KEY env var disables the client.""" + monkeypatch.setenv("LANGFUSE_PUBLIC_KEY", "pk-test") + monkeypatch.setenv("LANGFUSE_SECRET_KEY", "") + + client = Langfuse() + + assert isinstance(client._otel_tracer, NoOpTracer) + assert client._resources is None diff --git a/tests/unit/test_media.py b/tests/unit/test_media.py index 387eae745..861ffab0e 100644 --- a/tests/unit/test_media.py +++ b/tests/unit/test_media.py @@ -275,3 +275,28 @@ def test_init_with_urlsafe_base64_data_uri(): assert media._content_type == "application/octet-stream" assert media._content_bytes == original_bytes + +def test_parse_reference_string_skips_segment_without_equals(): + ref = "@@@langfuseMedia:type=image/jpeg|badpair|id=x|source=y@@@" + result = LangfuseMedia.parse_reference_string(ref) + + assert result["media_id"] == "x" + assert result["content_type"] == "image/jpeg" + assert result["source"] == "y" + + +def test_parse_reference_string_skips_trailing_empty_segment(): + ref = "@@@langfuseMedia:type=image/jpeg|id=x|source=y|@@@" + result = LangfuseMedia.parse_reference_string(ref) + + assert result["media_id"] == "x" + assert result["content_type"] == "image/jpeg" + assert result["source"] == "y" + + +def test_parse_reference_string_missing_required_fields_after_skipping_malformed_pair(): + with pytest.raises(ValueError, match="Missing required fields in reference string"): + LangfuseMedia.parse_reference_string( + "@@@langfuseMedia:type=image/jpeg|badpair@@@" + ) +