langfuse-haystack 0.6.4__tar.gz → 0.7.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {langfuse_haystack-0.6.4 → langfuse_haystack-0.7.0}/CHANGELOG.md +7 -0
- {langfuse_haystack-0.6.4 → langfuse_haystack-0.7.0}/PKG-INFO +1 -1
- {langfuse_haystack-0.6.4 → langfuse_haystack-0.7.0}/pyproject.toml +7 -1
- {langfuse_haystack-0.6.4 → langfuse_haystack-0.7.0}/src/haystack_integrations/components/connectors/langfuse/langfuse_connector.py +7 -0
- {langfuse_haystack-0.6.4 → langfuse_haystack-0.7.0}/src/haystack_integrations/tracing/langfuse/tracer.py +5 -1
- {langfuse_haystack-0.6.4 → langfuse_haystack-0.7.0}/tests/test_tracing.py +25 -1
- {langfuse_haystack-0.6.4 → langfuse_haystack-0.7.0}/.gitignore +0 -0
- {langfuse_haystack-0.6.4 → langfuse_haystack-0.7.0}/LICENSE.txt +0 -0
- {langfuse_haystack-0.6.4 → langfuse_haystack-0.7.0}/README.md +0 -0
- {langfuse_haystack-0.6.4 → langfuse_haystack-0.7.0}/example/basic_rag.py +0 -0
- {langfuse_haystack-0.6.4 → langfuse_haystack-0.7.0}/example/chat.py +0 -0
- {langfuse_haystack-0.6.4 → langfuse_haystack-0.7.0}/example/requirements.txt +0 -0
- {langfuse_haystack-0.6.4 → langfuse_haystack-0.7.0}/pydoc/config.yml +0 -0
- {langfuse_haystack-0.6.4 → langfuse_haystack-0.7.0}/src/haystack_integrations/components/connectors/langfuse/__init__.py +0 -0
- {langfuse_haystack-0.6.4 → langfuse_haystack-0.7.0}/src/haystack_integrations/tracing/langfuse/__init__.py +0 -0
- {langfuse_haystack-0.6.4 → langfuse_haystack-0.7.0}/tests/__init__.py +0 -0
- {langfuse_haystack-0.6.4 → langfuse_haystack-0.7.0}/tests/test_langfuse_span.py +0 -0
- {langfuse_haystack-0.6.4 → langfuse_haystack-0.7.0}/tests/test_tracer.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: langfuse-haystack
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.7.0
|
|
4
4
|
Project-URL: Documentation, https://github.com/deepset-ai/haystack-core-integrations/tree/main/integrations/langfuse#readme
|
|
5
5
|
Project-URL: Issues, https://github.com/deepset-ai/haystack-core-integrations/issues
|
|
6
6
|
Project-URL: Source, https://github.com/deepset-ai/haystack-core-integrations/tree/main/integrations/langfuse
|
|
@@ -67,7 +67,12 @@ python = ["3.8", "3.9", "3.10", "3.11", "3.12"]
|
|
|
67
67
|
[tool.hatch.envs.lint]
|
|
68
68
|
installer = "uv"
|
|
69
69
|
detached = true
|
|
70
|
-
dependencies = [
|
|
70
|
+
dependencies = [
|
|
71
|
+
"pip",
|
|
72
|
+
"black>=23.1.0",
|
|
73
|
+
"mypy>=1.0.0",
|
|
74
|
+
"ruff>=0.0.243",
|
|
75
|
+
]
|
|
71
76
|
|
|
72
77
|
[tool.hatch.envs.lint.scripts]
|
|
73
78
|
typing = "mypy --install-types --non-interactive --explicit-package-bases {args:src/ tests}"
|
|
@@ -167,6 +172,7 @@ module = [
|
|
|
167
172
|
"haystack_integrations.*",
|
|
168
173
|
"pytest.*",
|
|
169
174
|
"numpy.*",
|
|
175
|
+
"httpx.*",
|
|
170
176
|
]
|
|
171
177
|
ignore_missing_imports = true
|
|
172
178
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
from typing import Any, Dict, Optional
|
|
2
2
|
|
|
3
|
+
import httpx
|
|
3
4
|
from haystack import component, default_from_dict, default_to_dict, logging, tracing
|
|
4
5
|
from haystack.utils import Secret, deserialize_secrets_inplace
|
|
5
6
|
|
|
@@ -101,6 +102,7 @@ class LangfuseConnector:
|
|
|
101
102
|
public: bool = False,
|
|
102
103
|
public_key: Optional[Secret] = Secret.from_env_var("LANGFUSE_PUBLIC_KEY"), # noqa: B008
|
|
103
104
|
secret_key: Optional[Secret] = Secret.from_env_var("LANGFUSE_SECRET_KEY"), # noqa: B008
|
|
105
|
+
httpx_client: Optional[httpx.Client] = None,
|
|
104
106
|
):
|
|
105
107
|
"""
|
|
106
108
|
Initialize the LangfuseConnector component.
|
|
@@ -112,6 +114,9 @@ class LangfuseConnector:
|
|
|
112
114
|
only accessible to the Langfuse account owner. The default is `False`.
|
|
113
115
|
:param public_key: The Langfuse public key. Defaults to reading from LANGFUSE_PUBLIC_KEY environment variable.
|
|
114
116
|
:param secret_key: The Langfuse secret key. Defaults to reading from LANGFUSE_SECRET_KEY environment variable.
|
|
117
|
+
:param httpx_client: Optional custom httpx.Client instance to use for Langfuse API calls. Note that when
|
|
118
|
+
deserializing a pipeline from YAML, any custom client is discarded and Langfuse will create its own default
|
|
119
|
+
client, since HTTPX clients cannot be serialized.
|
|
115
120
|
"""
|
|
116
121
|
self.name = name
|
|
117
122
|
self.public = public
|
|
@@ -121,6 +126,7 @@ class LangfuseConnector:
|
|
|
121
126
|
tracer=Langfuse(
|
|
122
127
|
secret_key=secret_key.resolve_value() if secret_key else None,
|
|
123
128
|
public_key=public_key.resolve_value() if public_key else None,
|
|
129
|
+
httpx_client=httpx_client,
|
|
124
130
|
),
|
|
125
131
|
name=name,
|
|
126
132
|
public=public,
|
|
@@ -158,6 +164,7 @@ class LangfuseConnector:
|
|
|
158
164
|
public=self.public,
|
|
159
165
|
secret_key=self.secret_key.to_dict() if self.secret_key else None,
|
|
160
166
|
public_key=self.public_key.to_dict() if self.public_key else None,
|
|
167
|
+
# Note: httpx_client is not serialized as it's not serializable
|
|
161
168
|
)
|
|
162
169
|
|
|
163
170
|
@classmethod
|
|
@@ -201,7 +201,11 @@ class LangfuseTracer(Tracer):
|
|
|
201
201
|
)
|
|
202
202
|
|
|
203
203
|
raw_span = span.raw_span()
|
|
204
|
-
|
|
204
|
+
|
|
205
|
+
# In this section, we finalize both regular spans and generation spans created using the LangfuseSpan class.
|
|
206
|
+
# It's important to end() these spans to ensure they are properly closed and all relevant data is recorded.
|
|
207
|
+
# Note that we do not call end() on the main trace span itself, as its lifecycle is managed differently.
|
|
208
|
+
if isinstance(raw_span, (langfuse.client.StatefulSpanClient, langfuse.client.StatefulGenerationClient)):
|
|
205
209
|
raw_span.end()
|
|
206
210
|
self._context.pop()
|
|
207
211
|
|
|
@@ -10,6 +10,7 @@ from haystack.components.generators.chat import OpenAIChatGenerator
|
|
|
10
10
|
from haystack.dataclasses import ChatMessage
|
|
11
11
|
from haystack.utils import Secret
|
|
12
12
|
from requests.auth import HTTPBasicAuth
|
|
13
|
+
import httpx
|
|
13
14
|
|
|
14
15
|
from haystack_integrations.components.connectors.langfuse import LangfuseConnector
|
|
15
16
|
from haystack_integrations.components.generators.anthropic import AnthropicChatGenerator
|
|
@@ -49,6 +50,27 @@ def pipeline_with_secrets(llm_class, expected_trace):
|
|
|
49
50
|
return pipe
|
|
50
51
|
|
|
51
52
|
|
|
53
|
+
@pytest.fixture
|
|
54
|
+
def pipeline_with_custom_client(llm_class, expected_trace):
|
|
55
|
+
"""Pipeline factory using custom httpx client for Langfuse"""
|
|
56
|
+
pipe = Pipeline()
|
|
57
|
+
custom_client = httpx.Client(timeout=30.0) # Custom timeout of 30 seconds
|
|
58
|
+
pipe.add_component(
|
|
59
|
+
"tracer",
|
|
60
|
+
LangfuseConnector(
|
|
61
|
+
name=f"Chat example - {expected_trace}",
|
|
62
|
+
public=True,
|
|
63
|
+
secret_key=Secret.from_env_var("LANGFUSE_SECRET_KEY"),
|
|
64
|
+
public_key=Secret.from_env_var("LANGFUSE_PUBLIC_KEY"),
|
|
65
|
+
httpx_client=custom_client,
|
|
66
|
+
),
|
|
67
|
+
)
|
|
68
|
+
pipe.add_component("prompt_builder", ChatPromptBuilder())
|
|
69
|
+
pipe.add_component("llm", llm_class())
|
|
70
|
+
pipe.connect("prompt_builder.prompt", "llm.messages")
|
|
71
|
+
return pipe
|
|
72
|
+
|
|
73
|
+
|
|
52
74
|
@pytest.mark.integration
|
|
53
75
|
@pytest.mark.parametrize(
|
|
54
76
|
"llm_class, env_var, expected_trace",
|
|
@@ -58,7 +80,9 @@ def pipeline_with_secrets(llm_class, expected_trace):
|
|
|
58
80
|
(CohereChatGenerator, "COHERE_API_KEY", "Cohere"),
|
|
59
81
|
],
|
|
60
82
|
)
|
|
61
|
-
@pytest.mark.parametrize(
|
|
83
|
+
@pytest.mark.parametrize(
|
|
84
|
+
"pipeline_fixture", ["pipeline_with_env_vars", "pipeline_with_secrets", "pipeline_with_custom_client"]
|
|
85
|
+
)
|
|
62
86
|
def test_tracing_integration(llm_class, env_var, expected_trace, pipeline_fixture, request):
|
|
63
87
|
if not all([os.environ.get("LANGFUSE_SECRET_KEY"), os.environ.get("LANGFUSE_PUBLIC_KEY"), os.environ.get(env_var)]):
|
|
64
88
|
pytest.skip(f"Missing required environment variables: LANGFUSE_SECRET_KEY, LANGFUSE_PUBLIC_KEY, or {env_var}")
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|