huggingface-api-haystack 2.0.0__tar.gz → 3.0.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.
Files changed (35) hide show
  1. {huggingface_api_haystack-2.0.0 → huggingface_api_haystack-3.0.0}/CHANGELOG.md +18 -0
  2. {huggingface_api_haystack-2.0.0 → huggingface_api_haystack-3.0.0}/PKG-INFO +3 -3
  3. {huggingface_api_haystack-2.0.0 → huggingface_api_haystack-3.0.0}/pyproject.toml +2 -2
  4. {huggingface_api_haystack-2.0.0 → huggingface_api_haystack-3.0.0}/src/haystack_integrations/components/generators/huggingface_api/chat/chat_generator.py +5 -18
  5. {huggingface_api_haystack-2.0.0 → huggingface_api_haystack-3.0.0}/src/haystack_integrations/components/rankers/huggingface_api/ranker.py +1 -1
  6. {huggingface_api_haystack-2.0.0 → huggingface_api_haystack-3.0.0}/tests/test_chat_generator.py +2 -111
  7. {huggingface_api_haystack-2.0.0 → huggingface_api_haystack-3.0.0}/.gitignore +0 -0
  8. {huggingface_api_haystack-2.0.0 → huggingface_api_haystack-3.0.0}/LICENSE.txt +0 -0
  9. {huggingface_api_haystack-2.0.0 → huggingface_api_haystack-3.0.0}/README.md +0 -0
  10. {huggingface_api_haystack-2.0.0 → huggingface_api_haystack-3.0.0}/docker-compose.yml +0 -0
  11. {huggingface_api_haystack-2.0.0 → huggingface_api_haystack-3.0.0}/pydoc/config_docusaurus.yml +0 -0
  12. {huggingface_api_haystack-2.0.0 → huggingface_api_haystack-3.0.0}/src/haystack_integrations/common/huggingface_api/__init__.py +0 -0
  13. {huggingface_api_haystack-2.0.0 → huggingface_api_haystack-3.0.0}/src/haystack_integrations/common/huggingface_api/utils.py +0 -0
  14. {huggingface_api_haystack-2.0.0 → huggingface_api_haystack-3.0.0}/src/haystack_integrations/common/py.typed +0 -0
  15. {huggingface_api_haystack-2.0.0 → huggingface_api_haystack-3.0.0}/src/haystack_integrations/components/embedders/huggingface_api/__init__.py +0 -0
  16. {huggingface_api_haystack-2.0.0 → huggingface_api_haystack-3.0.0}/src/haystack_integrations/components/embedders/huggingface_api/document_embedder.py +0 -0
  17. {huggingface_api_haystack-2.0.0 → huggingface_api_haystack-3.0.0}/src/haystack_integrations/components/embedders/huggingface_api/sparse_document_embedder.py +0 -0
  18. {huggingface_api_haystack-2.0.0 → huggingface_api_haystack-3.0.0}/src/haystack_integrations/components/embedders/huggingface_api/sparse_embedding_utils.py +0 -0
  19. {huggingface_api_haystack-2.0.0 → huggingface_api_haystack-3.0.0}/src/haystack_integrations/components/embedders/huggingface_api/sparse_text_embedder.py +0 -0
  20. {huggingface_api_haystack-2.0.0 → huggingface_api_haystack-3.0.0}/src/haystack_integrations/components/embedders/huggingface_api/text_embedder.py +0 -0
  21. {huggingface_api_haystack-2.0.0 → huggingface_api_haystack-3.0.0}/src/haystack_integrations/components/embedders/py.typed +0 -0
  22. {huggingface_api_haystack-2.0.0 → huggingface_api_haystack-3.0.0}/src/haystack_integrations/components/generators/huggingface_api/__init__.py +0 -0
  23. {huggingface_api_haystack-2.0.0 → huggingface_api_haystack-3.0.0}/src/haystack_integrations/components/generators/huggingface_api/chat/__init__.py +0 -0
  24. {huggingface_api_haystack-2.0.0 → huggingface_api_haystack-3.0.0}/src/haystack_integrations/components/generators/py.typed +0 -0
  25. {huggingface_api_haystack-2.0.0 → huggingface_api_haystack-3.0.0}/src/haystack_integrations/components/rankers/huggingface_api/__init__.py +0 -0
  26. {huggingface_api_haystack-2.0.0 → huggingface_api_haystack-3.0.0}/src/haystack_integrations/components/rankers/py.typed +0 -0
  27. {huggingface_api_haystack-2.0.0 → huggingface_api_haystack-3.0.0}/tests/__init__.py +0 -0
  28. {huggingface_api_haystack-2.0.0 → huggingface_api_haystack-3.0.0}/tests/conftest.py +0 -0
  29. {huggingface_api_haystack-2.0.0 → huggingface_api_haystack-3.0.0}/tests/test_document_embedder.py +0 -0
  30. {huggingface_api_haystack-2.0.0 → huggingface_api_haystack-3.0.0}/tests/test_files/apple.jpg +0 -0
  31. {huggingface_api_haystack-2.0.0 → huggingface_api_haystack-3.0.0}/tests/test_ranker.py +0 -0
  32. {huggingface_api_haystack-2.0.0 → huggingface_api_haystack-3.0.0}/tests/test_sparse_document_embedder.py +0 -0
  33. {huggingface_api_haystack-2.0.0 → huggingface_api_haystack-3.0.0}/tests/test_sparse_text_embedder.py +0 -0
  34. {huggingface_api_haystack-2.0.0 → huggingface_api_haystack-3.0.0}/tests/test_text_embedder.py +0 -0
  35. {huggingface_api_haystack-2.0.0 → huggingface_api_haystack-3.0.0}/tests/test_utils.py +0 -0
@@ -1,5 +1,23 @@
1
1
  # Changelog
2
2
 
3
+ ## [integrations/huggingface_api-v2.1.0] - 2026-10-06
4
+
5
+ ### 🚜 Refactor
6
+
7
+ - [**breaking**] HF API - Stop warming up tools in Chat Generator (#4056)
8
+
9
+
10
+ ## [integrations/huggingface_api-v2.0.0] - 2026-10-01
11
+
12
+ ### 🚀 Features
13
+
14
+ - [**breaking**] Add grpc support for the huggingface TEI components; rename HuggingFace API Sparse Embedders -> Hugging Face TEI Sparse Embedders (#3870)
15
+
16
+ ### 🧪 Testing
17
+
18
+ - HF API - use Groq for gpt-oss-20b (#4001)
19
+
20
+
3
21
  ## [integrations/huggingface_api-v1.0.0] - 2026-09-07
4
22
 
5
23
  ### 🚀 Features
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: huggingface-api-haystack
3
- Version: 2.0.0
3
+ Version: 3.0.0
4
4
  Summary: Haystack integration for Hugging Face API
5
5
  Project-URL: Documentation, https://github.com/deepset-ai/haystack-core-integrations/tree/main/integrations/huggingface_api#readme
6
6
  Project-URL: Issues, https://github.com/deepset-ai/haystack-core-integrations/issues
@@ -11,14 +11,14 @@ License-File: LICENSE.txt
11
11
  Classifier: Development Status :: 4 - Beta
12
12
  Classifier: License :: OSI Approved :: Apache Software License
13
13
  Classifier: Programming Language :: Python
14
- Classifier: Programming Language :: Python :: 3.10
15
14
  Classifier: Programming Language :: Python :: 3.11
16
15
  Classifier: Programming Language :: Python :: 3.12
17
16
  Classifier: Programming Language :: Python :: 3.13
18
17
  Classifier: Programming Language :: Python :: 3.14
18
+ Classifier: Programming Language :: Python :: 3.15
19
19
  Classifier: Programming Language :: Python :: Implementation :: CPython
20
20
  Classifier: Programming Language :: Python :: Implementation :: PyPy
21
- Requires-Python: >=3.10
21
+ Requires-Python: >=3.11
22
22
  Requires-Dist: haystack-ai>=3.0.0
23
23
  Requires-Dist: httpx>=0.27.0
24
24
  Requires-Dist: huggingface-hub[inference]>=1.0.0
@@ -7,7 +7,7 @@ name = "huggingface-api-haystack"
7
7
  dynamic = ["version"]
8
8
  description = "Haystack integration for Hugging Face API"
9
9
  readme = "README.md"
10
- requires-python = ">=3.10"
10
+ requires-python = ">=3.11"
11
11
  license = "Apache-2.0"
12
12
  keywords = []
13
13
  authors = [{ name = "deepset GmbH", email = "info@deepset.ai" }]
@@ -15,11 +15,11 @@ classifiers = [
15
15
  "License :: OSI Approved :: Apache Software License",
16
16
  "Development Status :: 4 - Beta",
17
17
  "Programming Language :: Python",
18
- "Programming Language :: Python :: 3.10",
19
18
  "Programming Language :: Python :: 3.11",
20
19
  "Programming Language :: Python :: 3.12",
21
20
  "Programming Language :: Python :: 3.13",
22
21
  "Programming Language :: Python :: 3.14",
22
+ "Programming Language :: Python :: 3.15",
23
23
  "Programming Language :: Python :: Implementation :: CPython",
24
24
  "Programming Language :: Python :: Implementation :: PyPy",
25
25
  ]
@@ -5,7 +5,7 @@
5
5
  import inspect
6
6
  import json
7
7
  from collections.abc import AsyncIterable, Iterable
8
- from datetime import datetime, timezone
8
+ from datetime import UTC, datetime
9
9
  from typing import Any, Union
10
10
 
11
11
  from haystack import component, default_from_dict, default_to_dict, logging
@@ -27,7 +27,6 @@ from haystack.tools import (
27
27
  deserialize_tools_or_toolset_inplace,
28
28
  flatten_tools_or_toolsets,
29
29
  serialize_tools_or_toolset,
30
- warm_up_tools,
31
30
  )
32
31
  from haystack.utils import Secret, deserialize_callable, serialize_callable
33
32
  from haystack.utils.hf import convert_message_to_hf_format
@@ -222,7 +221,7 @@ def _convert_chat_completion_stream_output_to_streaming_chunk(
222
221
  usage = {"prompt_tokens": chunk.usage.prompt_tokens, "completion_tokens": chunk.usage.completion_tokens}
223
222
  return StreamingChunk(
224
223
  content="",
225
- meta={"model": chunk.model, "received_at": datetime.now(timezone.utc).isoformat(), "usage": usage},
224
+ meta={"model": chunk.model, "received_at": datetime.now(UTC).isoformat(), "usage": usage},
226
225
  component_info=component_info,
227
226
  )
228
227
 
@@ -239,7 +238,7 @@ def _convert_chat_completion_stream_output_to_streaming_chunk(
239
238
  content=choice.delta.content or "",
240
239
  meta={
241
240
  "model": chunk.model,
242
- "received_at": datetime.now(timezone.utc).isoformat(),
241
+ "received_at": datetime.now(UTC).isoformat(),
243
242
  "finish_reason": choice.finish_reason,
244
243
  },
245
244
  component_info=component_info,
@@ -442,7 +441,6 @@ class HuggingFaceAPIChatGenerator:
442
441
  self._model_or_url = model_or_url
443
442
  self._client: InferenceClient | None = None
444
443
  self._async_client: AsyncInferenceClient | None = None
445
- self._tools_warmed_up = False
446
444
 
447
445
  def _client_kwargs(self) -> dict[str, Any]:
448
446
  """Build the keyword arguments used to create Hugging Face clients."""
@@ -452,26 +450,15 @@ class HuggingFaceAPIChatGenerator:
452
450
  **{k: v for k, v in self.api_params.items() if k not in ("model", "url")},
453
451
  }
454
452
 
455
- def _warm_up_tools(self) -> None:
456
- if not self._tools_warmed_up:
457
- warm_up_tools(self.tools)
458
- self._tools_warmed_up = True
459
-
460
453
  def warm_up(self) -> None:
461
- """
462
- Warm up the Hugging Face API chat generator.
463
-
464
- This creates the synchronous client and warms up the configured tools.
465
- """
466
- self._warm_up_tools()
454
+ """Create the synchronous Hugging Face client."""
467
455
  if self._client is None:
468
456
  if self.api_type == HFGenerationAPIType.SERVERLESS_INFERENCE_API:
469
457
  _check_valid_model(self._model_or_url, HFModelType.GENERATION, self.token)
470
458
  self._client = InferenceClient(**self._client_kwargs())
471
459
 
472
460
  async def warm_up_async(self) -> None:
473
- """Create the asynchronous Hugging Face client and warm up the configured tools."""
474
- self._warm_up_tools()
461
+ """Create the asynchronous Hugging Face client."""
475
462
  if self._async_client is None:
476
463
  if self.api_type == HFGenerationAPIType.SERVERLESS_INFERENCE_API:
477
464
  await _check_valid_model_async(self._model_or_url, HFModelType.GENERATION, self.token)
@@ -21,7 +21,7 @@ with LazyImport("Run 'pip install \"huggingface-api-haystack[grpc]\"' for grpc s
21
21
  from grpc_requests.aio import AsyncClient
22
22
 
23
23
 
24
- class TruncationDirection(str, Enum):
24
+ class TruncationDirection(str, Enum): # noqa: UP042 # StrEnum would change str() of this public enum
25
25
  """
26
26
  Defines the direction to truncate text when input length exceeds the model's limit.
27
27
 
@@ -3,7 +3,7 @@
3
3
  # SPDX-License-Identifier: Apache-2.0
4
4
 
5
5
  import os
6
- from datetime import datetime, timezone
6
+ from datetime import UTC, datetime
7
7
  from typing import Any
8
8
  from unittest.mock import AsyncMock, MagicMock, Mock, patch
9
9
 
@@ -935,7 +935,7 @@ class TestSyncIntegration:
935
935
 
936
936
  response_meta = response["replies"][0].meta
937
937
  assert "completion_start_time" in response_meta
938
- assert datetime.fromisoformat(response_meta["completion_start_time"]) <= datetime.now(timezone.utc)
938
+ assert datetime.fromisoformat(response_meta["completion_start_time"]) <= datetime.now(UTC)
939
939
  assert "usage" in response_meta
940
940
  assert "prompt_tokens" in response_meta["usage"]
941
941
  assert response_meta["usage"]["prompt_tokens"] >= 0
@@ -1334,115 +1334,6 @@ class TestTools:
1334
1334
  assert hf_tools[0].function.description == "useful to determine the weather in a given location"
1335
1335
  assert hf_tools[0].function.parameters == {"city": {"type": "string"}}
1336
1336
 
1337
- def test_warm_up_with_tools(self, mock_check_valid_model):
1338
- """Test that warm_up() calls warm_up on tools and is idempotent."""
1339
-
1340
- # Create a mock tool that tracks if warm_up() was called
1341
- class MockTool(Tool):
1342
- warm_up_call_count = 0 # Class variable to track calls
1343
-
1344
- def __init__(self):
1345
- super().__init__(
1346
- name="mock_tool",
1347
- description="A mock tool for testing",
1348
- parameters={"x": {"type": "string"}},
1349
- function=lambda x: x,
1350
- )
1351
-
1352
- def warm_up(self):
1353
- MockTool.warm_up_call_count += 1
1354
-
1355
- # Reset the class variable before test
1356
- MockTool.warm_up_call_count = 0
1357
- mock_tool = MockTool()
1358
-
1359
- # Create HuggingFaceAPIChatGenerator with the mock tool
1360
- component = HuggingFaceAPIChatGenerator(
1361
- api_type=HFGenerationAPIType.SERVERLESS_INFERENCE_API,
1362
- api_params={"model": "HuggingFaceH4/zephyr-7b-alpha"},
1363
- tools=[mock_tool],
1364
- )
1365
-
1366
- # Verify initial state - warm_up not called yet
1367
- assert MockTool.warm_up_call_count == 0
1368
- assert not component._tools_warmed_up
1369
-
1370
- # Call warm_up() on the generator
1371
- component.warm_up()
1372
-
1373
- # Assert that the tool's warm_up() was called
1374
- assert MockTool.warm_up_call_count == 1
1375
- assert component._tools_warmed_up
1376
-
1377
- # Call warm_up() again and verify it's idempotent (only warms up once)
1378
- component.warm_up()
1379
-
1380
- # The tool's warm_up should still only have been called once
1381
- assert MockTool.warm_up_call_count == 1
1382
- assert component._tools_warmed_up
1383
-
1384
- def test_warm_up_with_no_tools(self, mock_check_valid_model):
1385
- """Test that warm_up() works when no tools are provided."""
1386
- component = HuggingFaceAPIChatGenerator(
1387
- api_type=HFGenerationAPIType.SERVERLESS_INFERENCE_API, api_params={"model": "HuggingFaceH4/zephyr-7b-alpha"}
1388
- )
1389
-
1390
- # Verify initial state
1391
- assert not component._tools_warmed_up
1392
- assert component.tools is None
1393
-
1394
- # Call warm_up() - should not raise an error
1395
- component.warm_up()
1396
-
1397
- # Verify the component is warmed up
1398
- assert component._tools_warmed_up
1399
-
1400
- # Call warm_up() again - should be idempotent
1401
- component.warm_up()
1402
- assert component._tools_warmed_up
1403
-
1404
- def test_warm_up_with_multiple_tools(self, mock_check_valid_model):
1405
- """Test that warm_up() works with multiple tools."""
1406
- # Track warm_up calls
1407
- warm_up_calls = []
1408
-
1409
- class MockTool(Tool):
1410
- def __init__(self, tool_name):
1411
- super().__init__(
1412
- name=tool_name,
1413
- description=f"Mock tool {tool_name}",
1414
- parameters={"type": "object", "properties": {"x": {"type": "string"}}, "required": ["x"]},
1415
- function=lambda x: f"{tool_name} result: {x}",
1416
- )
1417
-
1418
- def warm_up(self):
1419
- warm_up_calls.append(self.name)
1420
-
1421
- mock_tool1 = MockTool("tool1")
1422
- mock_tool2 = MockTool("tool2")
1423
-
1424
- # Use a LIST of tools, not a Toolset
1425
- component = HuggingFaceAPIChatGenerator(
1426
- api_type=HFGenerationAPIType.SERVERLESS_INFERENCE_API,
1427
- api_params={"model": "HuggingFaceH4/zephyr-7b-alpha"},
1428
- tools=[mock_tool1, mock_tool2],
1429
- )
1430
-
1431
- # Call warm_up()
1432
- component.warm_up()
1433
-
1434
- # Assert that both tools' warm_up() were called
1435
- assert "tool1" in warm_up_calls
1436
- assert "tool2" in warm_up_calls
1437
- assert component._tools_warmed_up
1438
-
1439
- # Track count
1440
- call_count = len(warm_up_calls)
1441
-
1442
- # Verify idempotency
1443
- component.warm_up()
1444
- assert len(warm_up_calls) == call_count
1445
-
1446
1337
 
1447
1338
  class TestReasoning:
1448
1339
  def test_run_with_reasoning_non_streaming(self, mock_check_valid_model, chat_messages):