Skip to content

Commit 33c2df5

Browse files
sjrlvblagoje
andauthored
chore: Remove ruff exclude and fix linting in Langfuse integration (#2257)
* Remove excludes for langfuse and fix linting * Fix linting in example folder * Update timezone * Post merge formatting --------- Co-authored-by: Vladimir Blagojevic <dovlex@gmail.com>
1 parent 8151019 commit 33c2df5

5 files changed

Lines changed: 29 additions & 40 deletions

File tree

integrations/langfuse/example/basic_rag.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,5 +62,5 @@ def get_pipeline(document_store: InMemoryDocumentStore):
6262
question = "What does Rhodes Statue look like?"
6363
response = pipeline.run({"text_embedder": {"text": question}, "prompt_builder": {"question": question}})
6464

65-
print(response["llm"]["replies"][0])
66-
print(response["tracer"]["trace_url"])
65+
print(response["llm"]["replies"][0]) # noqa: T201
66+
print(response["tracer"]["trace_url"]) # noqa: T201

integrations/langfuse/example/chat.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@
3636
selected_chat_generator = generators[selected_chat_generator]()
3737

3838
if __name__ == "__main__":
39-
4039
pipe = Pipeline()
4140
pipe.add_component("tracer", LangfuseConnector("Chat example"))
4241
pipe.add_component("prompt_builder", ChatPromptBuilder())
@@ -60,5 +59,5 @@
6059
},
6160
}
6261
)
63-
print(response["llm"]["replies"][0])
64-
print(response["tracer"]["trace_url"])
62+
print(response["llm"]["replies"][0]) # noqa: T201
63+
print(response["tracer"]["trace_url"]) # noqa: T201

integrations/langfuse/pyproject.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,6 @@ allow-direct-references = true
9393
[tool.ruff]
9494
target-version = "py38"
9595
line-length = 120
96-
exclude = ["example", "tests"]
9796

9897
[tool.ruff.lint]
9998
select = [

integrations/langfuse/tests/test_tracer.py

Lines changed: 21 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,10 @@
66
import datetime
77
import logging
88
import sys
9-
import json
109
from typing import Optional
1110
from unittest.mock import MagicMock, Mock, patch
1211

1312
import pytest
14-
from haystack import Pipeline, component
1513
from haystack.dataclasses import ChatMessage, ToolCall
1614

1715
from haystack_integrations.tracing.langfuse.tracer import (
@@ -21,7 +19,6 @@
2119
LangfuseTracer,
2220
SpanContext,
2321
)
24-
from haystack_integrations.components.connectors.langfuse import LangfuseConnector
2522

2623

2724
# Mock functions for Langfuse v3 API
@@ -78,7 +75,7 @@ def end(self):
7875

7976

8077
class MockTracer:
81-
def trace(self, name, **kwargs):
78+
def trace(self, name, **kwargs): # noqa: ARG002
8279
# Return a unique mock span for each trace call
8380
return MockSpan(name=name)
8481

@@ -92,10 +89,10 @@ class MockLangfuseClient:
9289
def __init__(self):
9390
self._mock_context_manager = MockContextManager()
9491

95-
def start_as_current_span(self, name=None, **kwargs):
92+
def start_as_current_span(self, _name=None, **_kwargs):
9693
return self._mock_context_manager
9794

98-
def start_as_current_observation(self, name=None, as_type=None, **kwargs):
95+
def start_as_current_observation(self, _name=None, _as_type=None, **_kwargs):
9996
return self._mock_context_manager
10097

10198
def get_current_trace_id(self):
@@ -230,7 +227,9 @@ def test_handle_chat_generator(self):
230227
assert mock_span.update.call_args_list[0][1] == {
231228
"usage": None,
232229
"model": "test_model",
233-
"completion_start_time": datetime.datetime(2021, 7, 27, 16, 2, 8, 12345),
230+
"completion_start_time": datetime.datetime( # noqa: DTZ001
231+
2021, 7, 27, 16, 2, 8, 12345
232+
),
234233
}
235234

236235
def test_handle_bad_completion_start_time(self, caplog):
@@ -302,18 +301,15 @@ def test_create_new_span(self):
302301
mock_raw_span.operation_name = "operation_name"
303302
mock_raw_span.metadata = {"tag1": "value1", "tag2": "value2"}
304303

305-
with patch("haystack_integrations.tracing.langfuse.tracer.LangfuseSpan") as MockLangfuseSpan, patch(
306-
"haystack_integrations.tracing.langfuse.tracer.langfuse.get_client"
307-
) as mock_get_client:
308-
mock_span_instance = MockLangfuseSpan.return_value
304+
with patch("haystack_integrations.tracing.langfuse.tracer.LangfuseSpan") as mock_langfuse_span:
305+
mock_span_instance = mock_langfuse_span.return_value
309306
mock_span_instance.raw_span.return_value = mock_raw_span
310307

311-
mock_client = mock_get_client()
312308
mock_context_manager = MockContextManager()
313309
mock_context_manager._span = mock_raw_span
314-
mock_client.start_as_current_span.return_value = mock_context_manager
315-
316310
mock_tracer = MagicMock()
311+
mock_tracer.start_as_current_span.return_value = mock_context_manager
312+
317313
tracer = LangfuseTracer(tracer=mock_tracer, name="Haystack", public=False)
318314

319315
# check that the trace method is called on the tracer instance with the provided operation name and tags
@@ -329,9 +325,7 @@ def test_create_new_span(self):
329325

330326
# check that update method is called on the span instance with the provided key value pairs
331327
def test_update_span_with_pipeline_input_output_data(self):
332-
with patch("haystack_integrations.tracing.langfuse.tracer.langfuse.get_client") as mock_get_client:
333-
mock_client = mock_get_client()
334-
328+
with patch("haystack_integrations.tracing.langfuse.tracer.langfuse.get_client"):
335329
tracer = LangfuseTracer(tracer=MockLangfuseClient(), name="Haystack", public=False)
336330
with tracer.trace(operation_name="operation_name", tags={"haystack.pipeline.input_data": "hello"}) as span:
337331
assert span.raw_span()._data["metadata"] == {"haystack.pipeline.input_data": "hello"}
@@ -340,9 +334,7 @@ def test_update_span_with_pipeline_input_output_data(self):
340334
assert span.raw_span()._data["metadata"] == {"haystack.pipeline.output_data": "bye"}
341335

342336
def test_trace_generation(self):
343-
with patch("haystack_integrations.tracing.langfuse.tracer.langfuse.get_client") as mock_get_client:
344-
mock_client = mock_get_client()
345-
337+
with patch("haystack_integrations.tracing.langfuse.tracer.langfuse.get_client"):
346338
tracer = LangfuseTracer(tracer=MockLangfuseClient(), name="Haystack", public=False)
347339
tags = {
348340
"haystack.component.type": "OpenAIChatGenerator",
@@ -358,7 +350,7 @@ def test_trace_generation(self):
358350
...
359351
assert span.raw_span()._data["usage"] is None
360352
assert span.raw_span()._data["model"] == "test_model"
361-
assert span.raw_span()._data["completion_start_time"] == datetime.datetime(2021, 7, 27, 16, 2, 8, 12345)
353+
assert span.raw_span()._data["completion_start_time"] == datetime.datetime(2021, 7, 27, 16, 2, 8, 12345) # noqa: DTZ001
362354

363355
def test_handle_tool_invoker(self):
364356
"""
@@ -402,7 +394,7 @@ def test_handle_tool_invoker(self):
402394
updated_name = name_update_call[1]["name"]
403395

404396
# verify the format of the updated span name to be: `original_component_name - [list_of_tool_names]`
405-
assert updated_name != "tool_invoker", f"Expected 'tool_invoker` to be upddated with tool names"
397+
assert updated_name != "tool_invoker", "Expected 'tool_invoker` to be upddated with tool names"
406398
assert " - " in updated_name, f"Expected ' - ' in {updated_name}"
407399
assert "[" in updated_name, f"Expected '[' in {updated_name}"
408400
assert "]" in updated_name, f"Expected ']' in {updated_name}"
@@ -411,9 +403,7 @@ def test_handle_tool_invoker(self):
411403
assert "weather_tool" in updated_name, f"Expected 'weather_tool' in {updated_name}"
412404

413405
def test_trace_generation_invalid_start_time(self):
414-
with patch("haystack_integrations.tracing.langfuse.tracer.langfuse.get_client") as mock_get_client:
415-
mock_client = mock_get_client()
416-
406+
with patch("haystack_integrations.tracing.langfuse.tracer.langfuse.get_client"):
417407
tracer = LangfuseTracer(tracer=MockLangfuseClient(), name="Haystack", public=False)
418408
tags = {
419409
"haystack.component.type": "OpenAIChatGenerator",
@@ -434,7 +424,7 @@ def test_update_span_gets_flushed_by_default(self):
434424
tracer_mock.flush = Mock() # Make flush a mock for assertions
435425

436426
tracer = LangfuseTracer(tracer=tracer_mock, name="Haystack", public=False)
437-
with tracer.trace(operation_name="operation_name", tags={"haystack.pipeline.input_data": "hello"}) as span:
427+
with tracer.trace(operation_name="operation_name", tags={"haystack.pipeline.input_data": "hello"}):
438428
pass
439429

440430
tracer_mock.flush.assert_called_once()
@@ -444,10 +434,11 @@ def test_update_span_flush_disable(self, monkeypatch):
444434
tracer_mock = MockLangfuseClient()
445435
tracer_mock.flush = Mock() # Make flush a mock for assertions
446436

447-
from haystack_integrations.tracing.langfuse.tracer import LangfuseTracer
437+
# Re-import LangfuseTracer to ensure it picks up the new environment variable
438+
from haystack_integrations.tracing.langfuse.tracer import LangfuseTracer # noqa: PLC0415
448439

449440
tracer = LangfuseTracer(tracer=tracer_mock, name="Haystack", public=False)
450-
with tracer.trace(operation_name="operation_name", tags={"haystack.pipeline.input_data": "hello"}) as span:
441+
with tracer.trace(operation_name="operation_name", tags={"haystack.pipeline.input_data": "hello"}):
451442
pass
452443

453444
tracer_mock.flush.assert_not_called()
@@ -456,7 +447,7 @@ def test_context_is_empty_after_tracing(self):
456447
tracer_mock = MockLangfuseClient()
457448

458449
tracer = LangfuseTracer(tracer=tracer_mock, name="Haystack", public=False)
459-
with tracer.trace(operation_name="operation_name", tags={"haystack.pipeline.input_data": "hello"}) as span:
450+
with tracer.trace(operation_name="operation_name", tags={"haystack.pipeline.input_data": "hello"}):
460451
pass
461452

462453
# Check behavioral state instead of internal _context list
@@ -471,7 +462,7 @@ def test_init_with_tracing_disabled(self, monkeypatch, caplog):
471462
# Re-import LangfuseTracer and instantiate it with tracing disabled
472463
with caplog.at_level(logging.WARNING):
473464
monkeypatch.setenv("HAYSTACK_CONTENT_TRACING_ENABLED", "false")
474-
from haystack_integrations.tracing.langfuse import LangfuseTracer
465+
from haystack_integrations.tracing.langfuse import LangfuseTracer # noqa: PLC0415
475466

476467
LangfuseTracer(tracer=MockLangfuseClient(), name="Haystack", public=False)
477468
assert "tracing is disabled" in caplog.text

integrations/langfuse/tests/test_tracing.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@
22
#
33
# SPDX-License-Identifier: Apache-2.0
44

5+
import json
56
import os
67
import time
78
from typing import Any, Dict, List
89
from urllib.parse import urlparse
9-
import json
1010

1111
import pytest
1212
import requests
@@ -38,7 +38,7 @@ def poll_langfuse(url: str):
3838

3939
res = None
4040
while attempts > 0:
41-
res = requests.get(url, auth=auth)
41+
res = requests.get(url, auth=auth, timeout=60.0)
4242
if res.status_code == 200:
4343
return res
4444

@@ -73,7 +73,7 @@ def basic_pipeline(llm_class, expected_trace):
7373
(CohereChatGenerator, "COHERE_API_KEY", "Cohere"),
7474
],
7575
)
76-
def test_tracing_integration(llm_class, env_var, expected_trace, basic_pipeline):
76+
def test_tracing_integration(env_var, expected_trace, basic_pipeline):
7777
if not all([os.environ.get("LANGFUSE_SECRET_KEY"), os.environ.get("LANGFUSE_PUBLIC_KEY"), os.environ.get(env_var)]):
7878
pytest.skip(f"Missing required environment variable: {env_var}")
7979

@@ -242,7 +242,7 @@ def run(self, input_data: str):
242242
# Test 1: First run will fail and should clean up context
243243
try:
244244
main_pipeline.run({"nested_component": {"input_data": "invalid json"}})
245-
except Exception:
245+
except Exception: # noqa: S110
246246
pass # Expected to fail
247247

248248
# Critical assertion: context should be empty after failed operation

0 commit comments

Comments
 (0)