huggingface-api-haystack 0.3.0__tar.gz → 0.5.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 (30) hide show
  1. huggingface_api_haystack-0.5.0/CHANGELOG.md +47 -0
  2. {huggingface_api_haystack-0.3.0 → huggingface_api_haystack-0.5.0}/PKG-INFO +4 -4
  3. {huggingface_api_haystack-0.3.0 → huggingface_api_haystack-0.5.0}/README.md +2 -2
  4. {huggingface_api_haystack-0.3.0 → huggingface_api_haystack-0.5.0}/pyproject.toml +1 -0
  5. {huggingface_api_haystack-0.3.0 → huggingface_api_haystack-0.5.0}/src/haystack_integrations/components/generators/huggingface_api/chat/chat_generator.py +12 -5
  6. {huggingface_api_haystack-0.3.0 → huggingface_api_haystack-0.5.0}/src/haystack_integrations/components/rankers/huggingface_api/ranker.py +1 -0
  7. {huggingface_api_haystack-0.3.0 → huggingface_api_haystack-0.5.0}/tests/conftest.py +10 -0
  8. {huggingface_api_haystack-0.3.0 → huggingface_api_haystack-0.5.0}/tests/test_chat_generator.py +42 -52
  9. {huggingface_api_haystack-0.3.0 → huggingface_api_haystack-0.5.0}/tests/test_ranker.py +8 -0
  10. huggingface_api_haystack-0.3.0/CHANGELOG.md +0 -20
  11. {huggingface_api_haystack-0.3.0 → huggingface_api_haystack-0.5.0}/.gitignore +0 -0
  12. {huggingface_api_haystack-0.3.0 → huggingface_api_haystack-0.5.0}/LICENSE.txt +0 -0
  13. {huggingface_api_haystack-0.3.0 → huggingface_api_haystack-0.5.0}/pydoc/config_docusaurus.yml +0 -0
  14. {huggingface_api_haystack-0.3.0 → huggingface_api_haystack-0.5.0}/src/haystack_integrations/common/huggingface_api/__init__.py +0 -0
  15. {huggingface_api_haystack-0.3.0 → huggingface_api_haystack-0.5.0}/src/haystack_integrations/common/huggingface_api/utils.py +0 -0
  16. {huggingface_api_haystack-0.3.0 → huggingface_api_haystack-0.5.0}/src/haystack_integrations/common/py.typed +0 -0
  17. {huggingface_api_haystack-0.3.0 → huggingface_api_haystack-0.5.0}/src/haystack_integrations/components/embedders/huggingface_api/__init__.py +0 -0
  18. {huggingface_api_haystack-0.3.0 → huggingface_api_haystack-0.5.0}/src/haystack_integrations/components/embedders/huggingface_api/document_embedder.py +0 -0
  19. {huggingface_api_haystack-0.3.0 → huggingface_api_haystack-0.5.0}/src/haystack_integrations/components/embedders/huggingface_api/text_embedder.py +0 -0
  20. {huggingface_api_haystack-0.3.0 → huggingface_api_haystack-0.5.0}/src/haystack_integrations/components/embedders/py.typed +0 -0
  21. {huggingface_api_haystack-0.3.0 → huggingface_api_haystack-0.5.0}/src/haystack_integrations/components/generators/huggingface_api/__init__.py +0 -0
  22. {huggingface_api_haystack-0.3.0 → huggingface_api_haystack-0.5.0}/src/haystack_integrations/components/generators/huggingface_api/chat/__init__.py +0 -0
  23. {huggingface_api_haystack-0.3.0 → huggingface_api_haystack-0.5.0}/src/haystack_integrations/components/generators/py.typed +0 -0
  24. {huggingface_api_haystack-0.3.0 → huggingface_api_haystack-0.5.0}/src/haystack_integrations/components/rankers/huggingface_api/__init__.py +0 -0
  25. {huggingface_api_haystack-0.3.0 → huggingface_api_haystack-0.5.0}/src/haystack_integrations/components/rankers/py.typed +0 -0
  26. {huggingface_api_haystack-0.3.0 → huggingface_api_haystack-0.5.0}/tests/__init__.py +0 -0
  27. {huggingface_api_haystack-0.3.0 → huggingface_api_haystack-0.5.0}/tests/test_document_embedder.py +0 -0
  28. {huggingface_api_haystack-0.3.0 → huggingface_api_haystack-0.5.0}/tests/test_files/apple.jpg +0 -0
  29. {huggingface_api_haystack-0.3.0 → huggingface_api_haystack-0.5.0}/tests/test_text_embedder.py +0 -0
  30. {huggingface_api_haystack-0.3.0 → huggingface_api_haystack-0.5.0}/tests/test_utils.py +0 -0
@@ -0,0 +1,47 @@
1
+ # Changelog
2
+
3
+ ## [unreleased]
4
+
5
+ ### 🧪 Testing
6
+
7
+ - Trust test modules under Haystack 3.0's deserialization allowlist (#3537)
8
+ - Make Tool/Agent serialization assertions version-agnostic for Haystack 2.x/3.x (#3533)
9
+
10
+ ### 🧹 Chores
11
+
12
+ - Support sync streaming callbacks in async contexts for Haystack 2.x/3.x compatibility (#3534)
13
+
14
+
15
+ ## [integrations/huggingface_api-v0.3.0] - 2026-06-26
16
+
17
+ ### 🐛 Bug Fixes
18
+
19
+ - Validate top_k in HuggingFaceTEIRanker (#3503)
20
+
21
+ ### 🧪 Testing
22
+
23
+ - Improve del_hf_env_vars fixture (#3428)
24
+
25
+ ### 🧹 Chores
26
+
27
+ - Improve consistency of integrations folder structure (#3430)
28
+
29
+
30
+ ## [integrations/huggingface_api-v0.2.0] - 2026-06-05
31
+
32
+ ### 🚀 Features
33
+
34
+ - Move HuggingFaceTEIRanker from Haystack (#3407)
35
+
36
+ ### 📚 Documentation
37
+
38
+ - Document raised exceptions in HF API components (#3406)
39
+
40
+
41
+ ## [integrations/huggingface_api-v0.1.0] - 2026-06-05
42
+
43
+ ### 🚀 Features
44
+
45
+ - Move HF API components to core integrations (#3403)
46
+
47
+ <!-- generated by git-cliff -->
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.4
1
+ Metadata-Version: 2.5
2
2
  Name: huggingface-api-haystack
3
- Version: 0.3.0
3
+ Version: 0.5.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
@@ -28,7 +28,7 @@ Description-Content-Type: text/markdown
28
28
  [![PyPI - Version](https://img.shields.io/pypi/v/huggingface-api-haystack.svg)](https://pypi.org/project/huggingface-api-haystack)
29
29
  [![PyPI - Python Version](https://img.shields.io/pypi/pyversions/huggingface-api-haystack.svg)](https://pypi.org/project/huggingface-api-haystack)
30
30
 
31
- - [Integration page](https://haystack.deepset.ai/integrations/huggingface_api)
31
+ - [Integration page](https://haystack.deepset.ai/integrations/huggingface-api)
32
32
  - [Changelog](https://github.com/deepset-ai/haystack-core-integrations/blob/main/integrations/huggingface_api/CHANGELOG.md)
33
33
 
34
34
  ---
@@ -37,4 +37,4 @@ Description-Content-Type: text/markdown
37
37
 
38
38
  Refer to the general [Contribution Guidelines](https://github.com/deepset-ai/haystack-core-integrations/blob/main/CONTRIBUTING.md).
39
39
 
40
- To run integration tests locally, you need to export the `HF_API_TOKEN` environment variable.
40
+ To run integration tests locally, you need to export the `HF_TOKEN` environment variable.
@@ -3,7 +3,7 @@
3
3
  [![PyPI - Version](https://img.shields.io/pypi/v/huggingface-api-haystack.svg)](https://pypi.org/project/huggingface-api-haystack)
4
4
  [![PyPI - Python Version](https://img.shields.io/pypi/pyversions/huggingface-api-haystack.svg)](https://pypi.org/project/huggingface-api-haystack)
5
5
 
6
- - [Integration page](https://haystack.deepset.ai/integrations/huggingface_api)
6
+ - [Integration page](https://haystack.deepset.ai/integrations/huggingface-api)
7
7
  - [Changelog](https://github.com/deepset-ai/haystack-core-integrations/blob/main/integrations/huggingface_api/CHANGELOG.md)
8
8
 
9
9
  ---
@@ -12,4 +12,4 @@
12
12
 
13
13
  Refer to the general [Contribution Guidelines](https://github.com/deepset-ai/haystack-core-integrations/blob/main/CONTRIBUTING.md).
14
14
 
15
- To run integration tests locally, you need to export the `HF_API_TOKEN` environment variable.
15
+ To run integration tests locally, you need to export the `HF_TOKEN` environment variable.
@@ -132,6 +132,7 @@ ignore = [
132
132
  "PLR0912",
133
133
  "PLR0913",
134
134
  "PLR0915",
135
+ "PLR0917",
135
136
  # Allow `Any` type - used legitimately for dynamic types and SDK boundaries
136
137
  "ANN401",
137
138
  ]
@@ -2,6 +2,7 @@
2
2
  #
3
3
  # SPDX-License-Identifier: Apache-2.0
4
4
 
5
+ import inspect
5
6
  import json
6
7
  from collections.abc import AsyncIterable, Iterable
7
8
  from datetime import datetime, timezone
@@ -10,7 +11,6 @@ from typing import Any, Union
10
11
  from haystack import component, default_from_dict, default_to_dict, logging
11
12
  from haystack.components.generators.utils import _convert_streaming_chunks_to_chat_message, _normalize_messages
12
13
  from haystack.dataclasses import (
13
- AsyncStreamingCallbackT,
14
14
  ChatMessage,
15
15
  ComponentInfo,
16
16
  ReasoningContent,
@@ -505,7 +505,9 @@ class HuggingFaceAPIChatGenerator:
505
505
  A list of ChatMessage objects representing the input messages. If a string is provided, it is converted
506
506
  to a list containing a ChatMessage with user role.
507
507
  :param generation_kwargs:
508
- Additional keyword arguments for text generation.
508
+ Additional keyword arguments for text generation. These are merged per key with the
509
+ `generation_kwargs` passed at initialization: keys provided here take precedence, keys set only
510
+ at initialization are kept.
509
511
  :param tools:
510
512
  A list of tools or a Toolset for which the model can prepare calls. If set, it will override
511
513
  the `tools` parameter set during component initialization. This parameter can accept either a
@@ -565,7 +567,9 @@ class HuggingFaceAPIChatGenerator:
565
567
  A list of ChatMessage objects representing the input messages. If a string is provided, it is converted
566
568
  to a list containing a ChatMessage with user role.
567
569
  :param generation_kwargs:
568
- Additional keyword arguments for text generation.
570
+ Additional keyword arguments for text generation. These are merged per key with the
571
+ `generation_kwargs` passed at initialization: keys provided here take precedence, keys set only
572
+ at initialization are kept.
569
573
  :param tools:
570
574
  A list of tools or a Toolset for which the model can prepare calls. If set, it will override the `tools`
571
575
  parameter set during component initialization. This parameter can accept either a list of `Tool` objects
@@ -680,7 +684,7 @@ class HuggingFaceAPIChatGenerator:
680
684
  self,
681
685
  messages: list[dict[str, str]],
682
686
  generation_kwargs: dict[str, Any],
683
- streaming_callback: AsyncStreamingCallbackT,
687
+ streaming_callback: StreamingCallbackT,
684
688
  ) -> dict[str, list[ChatMessage]]:
685
689
  api_output: AsyncIterable[ChatCompletionStreamOutput] = await self._async_client.chat_completion(
686
690
  messages,
@@ -696,7 +700,10 @@ class HuggingFaceAPIChatGenerator:
696
700
  chunk=chunk, previous_chunks=streaming_chunks, component_info=component_info
697
701
  )
698
702
  streaming_chunks.append(stream_chunk)
699
- await streaming_callback(stream_chunk)
703
+ # sync callbacks are allowed in async contexts with Haystack >= 3.0, so only await async ones
704
+ callback_result = streaming_callback(stream_chunk)
705
+ if inspect.isawaitable(callback_result):
706
+ await callback_result
700
707
 
701
708
  message = _convert_streaming_chunks_to_chat_message(chunks=streaming_chunks)
702
709
  if message.meta.get("usage") is None:
@@ -108,6 +108,7 @@ class HuggingFaceTEIRanker:
108
108
  self,
109
109
  url=self.url,
110
110
  top_k=self.top_k,
111
+ raw_scores=self.raw_scores,
111
112
  timeout=self.timeout,
112
113
  token=self.token,
113
114
  max_retries=self.max_retries,
@@ -27,3 +27,13 @@ def del_hf_env_vars_if_empty(monkeypatch):
27
27
  for var in ("HF_API_TOKEN", "HF_TOKEN"):
28
28
  if not os.environ.get(var, "").strip():
29
29
  monkeypatch.delenv(var, raising=False)
30
+
31
+
32
+ @pytest.fixture(autouse=True)
33
+ def allow_deserialization_of_test_modules(monkeypatch):
34
+ """
35
+ haystack-ai >= 3.0 refuses to deserialize classes and callables from modules outside its
36
+ trusted-module allowlist. Tools and callbacks defined in the test modules live outside that
37
+ allowlist, so trust them explicitly; haystack-ai 2.x ignores this environment variable.
38
+ """
39
+ monkeypatch.setenv("HAYSTACK_DESERIALIZATION_ALLOWLIST", "tests,test_*")
@@ -270,20 +270,10 @@ class TestHuggingFaceAPIChatGenerator:
270
270
  assert init_params["token"] == {"env_vars": ["HF_API_TOKEN", "HF_TOKEN"], "strict": False, "type": "env_var"}
271
271
  assert init_params["generation_kwargs"] == {"temperature": 0.6, "stop": ["stop", "words"], "max_tokens": 512}
272
272
  assert init_params["streaming_callback"] is None
273
- assert init_params["tools"] == [
274
- {
275
- "type": "haystack.tools.tool.Tool",
276
- "data": {
277
- "description": "description",
278
- "function": "builtins.print",
279
- "inputs_from_state": None,
280
- "name": "name",
281
- "outputs_to_state": None,
282
- "outputs_to_string": None,
283
- "parameters": {"x": {"type": "string"}},
284
- },
285
- }
286
- ]
273
+
274
+ # deserializing the serialized component must reproduce the original tool
275
+ loaded = HuggingFaceAPIChatGenerator.from_dict(result)
276
+ assert loaded.tools == [tool]
287
277
 
288
278
  def test_from_dict(self, mock_check_valid_model):
289
279
  tool = Tool(name="name", description="description", parameters={"x": {"type": "string"}}, function=print)
@@ -323,6 +313,11 @@ class TestHuggingFaceAPIChatGenerator:
323
313
  pipeline.add_component("generator", generator)
324
314
 
325
315
  pipeline_dict = pipeline.to_dict()
316
+
317
+ # the Tool serialization format is owned by haystack-ai and varies across its versions; the
318
+ # dumps/loads round-trip below covers the tools, so exclude them from the pinned-dict comparison
319
+ tools_entries = pipeline_dict["components"]["generator"]["init_parameters"].pop("tools")
320
+ assert len(tools_entries) == 1
326
321
  assert pipeline_dict == {
327
322
  "metadata": {},
328
323
  "max_runs_per_component": 100,
@@ -337,20 +332,6 @@ class TestHuggingFaceAPIChatGenerator:
337
332
  "token": {"type": "env_var", "env_vars": ["ENV_VAR"], "strict": False},
338
333
  "generation_kwargs": {"temperature": 0.6, "stop": ["stop", "words"], "max_tokens": 512},
339
334
  "streaming_callback": None,
340
- "tools": [
341
- {
342
- "type": "haystack.tools.tool.Tool",
343
- "data": {
344
- "inputs_from_state": None,
345
- "name": "name",
346
- "outputs_to_state": None,
347
- "outputs_to_string": None,
348
- "description": "description",
349
- "parameters": {"x": {"type": "string"}},
350
- "function": "builtins.print",
351
- },
352
- }
353
- ],
354
335
  },
355
336
  }
356
337
  },
@@ -393,6 +374,19 @@ class TestHuggingFaceAPIChatGenerator:
393
374
  assert len(response["replies"]) == 1
394
375
  assert [isinstance(reply, ChatMessage) for reply in response["replies"]]
395
376
 
377
+ def test_run_with_generation_kwargs(self, mock_check_valid_model, mock_chat_completion, chat_messages):
378
+ generator = HuggingFaceAPIChatGenerator(
379
+ api_type=HFGenerationAPIType.SERVERLESS_INFERENCE_API,
380
+ api_params={"model": "meta-llama/Llama-2-13b-chat-hf"},
381
+ generation_kwargs={"max_tokens": 100, "temperature": 0.5},
382
+ )
383
+
384
+ generator.run(messages=chat_messages, generation_kwargs={"temperature": 0.9})
385
+
386
+ _, kwargs = mock_chat_completion.call_args
387
+ assert kwargs["max_tokens"] == 100
388
+ assert kwargs["temperature"] == 0.9
389
+
396
390
  def test_run_with_string_input(self, mock_check_valid_model, mock_chat_completion):
397
391
  generator = HuggingFaceAPIChatGenerator(
398
392
  api_type=HFGenerationAPIType.SERVERLESS_INFERENCE_API,
@@ -933,6 +927,22 @@ class TestHuggingFaceAPIChatGenerator:
933
927
  assert len(response["replies"]) == 1
934
928
  assert [isinstance(reply, ChatMessage) for reply in response["replies"]]
935
929
 
930
+ @pytest.mark.asyncio
931
+ async def test_run_async_with_generation_kwargs(
932
+ self, mock_check_valid_model, mock_chat_completion_async, chat_messages
933
+ ):
934
+ generator = HuggingFaceAPIChatGenerator(
935
+ api_type=HFGenerationAPIType.SERVERLESS_INFERENCE_API,
936
+ api_params={"model": "meta-llama/Llama-2-13b-chat-hf"},
937
+ generation_kwargs={"max_tokens": 100, "temperature": 0.5},
938
+ )
939
+
940
+ await generator.run_async(messages=chat_messages, generation_kwargs={"temperature": 0.9})
941
+
942
+ _, kwargs = mock_chat_completion_async.call_args
943
+ assert kwargs["max_tokens"] == 100
944
+ assert kwargs["temperature"] == 0.9
945
+
936
946
  @pytest.mark.asyncio
937
947
  async def test_run_async_with_string_input(self, mock_check_valid_model, mock_chat_completion_async):
938
948
  generator = HuggingFaceAPIChatGenerator(
@@ -1189,30 +1199,10 @@ class TestHuggingFaceAPIChatGenerator:
1189
1199
  )
1190
1200
  data = generator.to_dict()
1191
1201
 
1192
- expected_tools_data = {
1193
- "type": "haystack.tools.toolset.Toolset",
1194
- "data": {
1195
- "tools": [
1196
- {
1197
- "type": "haystack.tools.tool.Tool",
1198
- "data": {
1199
- "name": "weather",
1200
- "description": "useful to determine the weather in a given location",
1201
- "parameters": {
1202
- "type": "object",
1203
- "properties": {"city": {"type": "string"}},
1204
- "required": ["city"],
1205
- },
1206
- "function": "tests.test_chat_generator.get_weather",
1207
- "outputs_to_string": None,
1208
- "inputs_from_state": None,
1209
- "outputs_to_state": None,
1210
- },
1211
- }
1212
- ]
1213
- },
1214
- }
1215
- assert data["init_parameters"]["tools"] == expected_tools_data
1202
+ # deserializing the serialized component must reproduce the original toolset
1203
+ loaded = HuggingFaceAPIChatGenerator.from_dict(data)
1204
+ assert isinstance(loaded.tools, Toolset)
1205
+ assert list(loaded.tools) == list(toolset)
1216
1206
 
1217
1207
  def test_convert_tools_to_hfapi_tools(self):
1218
1208
  assert _convert_tools_to_hfapi_tools(None) is None
@@ -60,6 +60,14 @@ class TestHuggingFaceTEIRanker:
60
60
  assert data["init_parameters"]["max_retries"] == 4
61
61
  assert data["init_parameters"]["retry_status_codes"] == [500, 502]
62
62
 
63
+ def test_raw_scores_survives_a_serialization_round_trip(self, del_hf_env_vars_if_empty):
64
+ """raw_scores goes into the request payload, so losing it changes what the API returns."""
65
+ ranker = HuggingFaceTEIRanker(url="https://api.my-tei-service.com", raw_scores=True)
66
+
67
+ restored = HuggingFaceTEIRanker.from_dict(ranker.to_dict())
68
+
69
+ assert restored.raw_scores is True
70
+
63
71
  def test_from_dict(self, del_hf_env_vars_if_empty):
64
72
  """Test deserialization from dict with environment variable token"""
65
73
  data = {
@@ -1,20 +0,0 @@
1
- # Changelog
2
-
3
- ## [integrations/huggingface_api-v0.2.0] - 2026-06-05
4
-
5
- ### 🚀 Features
6
-
7
- - Move HuggingFaceTEIRanker from Haystack (#3407)
8
-
9
- ### 📚 Documentation
10
-
11
- - Document raised exceptions in HF API components (#3406)
12
-
13
-
14
- ## [integrations/huggingface_api-v0.1.0] - 2026-06-05
15
-
16
- ### 🚀 Features
17
-
18
- - Move HF API components to core integrations (#3403)
19
-
20
- <!-- generated by git-cliff -->