fastembed-haystack 1.6.0__tar.gz → 2.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 (28) hide show
  1. {fastembed_haystack-1.6.0 → fastembed_haystack-2.0.0}/CHANGELOG.md +26 -0
  2. {fastembed_haystack-1.6.0 → fastembed_haystack-2.0.0}/PKG-INFO +3 -4
  3. {fastembed_haystack-1.6.0 → fastembed_haystack-2.0.0}/pyproject.toml +2 -8
  4. {fastembed_haystack-1.6.0 → fastembed_haystack-2.0.0}/src/haystack_integrations/components/embedders/fastembed/embedding_backend/fastembed_backend.py +11 -11
  5. {fastembed_haystack-1.6.0 → fastembed_haystack-2.0.0}/src/haystack_integrations/components/embedders/fastembed/fastembed_document_embedder.py +7 -7
  6. {fastembed_haystack-1.6.0 → fastembed_haystack-2.0.0}/src/haystack_integrations/components/embedders/fastembed/fastembed_sparse_document_embedder.py +8 -8
  7. {fastembed_haystack-1.6.0 → fastembed_haystack-2.0.0}/src/haystack_integrations/components/embedders/fastembed/fastembed_sparse_text_embedder.py +6 -6
  8. {fastembed_haystack-1.6.0 → fastembed_haystack-2.0.0}/src/haystack_integrations/components/embedders/fastembed/fastembed_text_embedder.py +5 -5
  9. {fastembed_haystack-1.6.0 → fastembed_haystack-2.0.0}/src/haystack_integrations/components/rankers/fastembed/ranker.py +8 -8
  10. {fastembed_haystack-1.6.0 → fastembed_haystack-2.0.0}/tests/test_fastembed_document_embedder.py +1 -0
  11. {fastembed_haystack-1.6.0 → fastembed_haystack-2.0.0}/tests/test_fastembed_ranker.py +2 -0
  12. {fastembed_haystack-1.6.0 → fastembed_haystack-2.0.0}/tests/test_fastembed_sparse_document_embedder.py +1 -1
  13. {fastembed_haystack-1.6.0 → fastembed_haystack-2.0.0}/.gitignore +0 -0
  14. {fastembed_haystack-1.6.0 → fastembed_haystack-2.0.0}/LICENSE.txt +0 -0
  15. {fastembed_haystack-1.6.0 → fastembed_haystack-2.0.0}/README.md +0 -0
  16. {fastembed_haystack-1.6.0 → fastembed_haystack-2.0.0}/examples/example.py +0 -0
  17. {fastembed_haystack-1.6.0 → fastembed_haystack-2.0.0}/examples/ranker_example.py +0 -0
  18. {fastembed_haystack-1.6.0 → fastembed_haystack-2.0.0}/examples/sparse_example.py +0 -0
  19. {fastembed_haystack-1.6.0 → fastembed_haystack-2.0.0}/pydoc/config_docusaurus.yml +0 -0
  20. {fastembed_haystack-1.6.0 → fastembed_haystack-2.0.0}/src/haystack_integrations/components/embedders/fastembed/__init__.py +0 -0
  21. {fastembed_haystack-1.6.0 → fastembed_haystack-2.0.0}/src/haystack_integrations/components/embedders/fastembed/embedding_backend/__init__.py +0 -0
  22. {fastembed_haystack-1.6.0 → fastembed_haystack-2.0.0}/src/haystack_integrations/components/embedders/py.typed +0 -0
  23. {fastembed_haystack-1.6.0 → fastembed_haystack-2.0.0}/src/haystack_integrations/components/rankers/fastembed/__init__.py +0 -0
  24. {fastembed_haystack-1.6.0 → fastembed_haystack-2.0.0}/src/haystack_integrations/components/rankers/py.typed +0 -0
  25. {fastembed_haystack-1.6.0 → fastembed_haystack-2.0.0}/tests/__init__.py +0 -0
  26. {fastembed_haystack-1.6.0 → fastembed_haystack-2.0.0}/tests/test_fastembed_backend.py +0 -0
  27. {fastembed_haystack-1.6.0 → fastembed_haystack-2.0.0}/tests/test_fastembed_sparse_text_embedder.py +0 -0
  28. {fastembed_haystack-1.6.0 → fastembed_haystack-2.0.0}/tests/test_fastembed_text_embedder.py +0 -0
@@ -1,5 +1,31 @@
1
1
  # Changelog
2
2
 
3
+ ## [integrations/fastembed-v1.6.0] - 2026-01-09
4
+
5
+ ### 🚀 Features
6
+
7
+ - Update FastEmbed components to auto call run `warm_up` and don't modify Documents in place (#2678)
8
+
9
+ ### 📚 Documentation
10
+
11
+ - Add pydoc configurations for Docusaurus (#2411)
12
+
13
+ ### ⚙️ CI
14
+
15
+ - Change pytest command (#2475)
16
+
17
+ ### 🧹 Chores
18
+
19
+ - Remove black (#1985)
20
+ - Standardize readmes - part 1 (#2202)
21
+ - Fix linting fastembed (#2254)
22
+ - Remove Readme API CI workflow and configs (#2573)
23
+ - Make fmt command more forgiving (#2671)
24
+
25
+ ### 🌀 Miscellaneous
26
+
27
+ - Adopt PEP 585 type hinting (part 3) (#2510)
28
+
3
29
  ## [integrations/fastembed-v1.5.0] - 2025-06-17
4
30
 
5
31
  ### 🐛 Bug Fixes
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fastembed-haystack
3
- Version: 1.6.0
3
+ Version: 2.0.0
4
4
  Summary: Haystack 2.x component to embed strings and Documents using fastembed embedding model
5
5
  Project-URL: Source, https://github.com/deepset-ai/haystack-core-integrations
6
6
  Project-URL: Documentation, https://github.com/deepset-ai/haystack-core-integrations/blob/main/integrations/fastembed/README.md
@@ -11,16 +11,15 @@ 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.9
15
14
  Classifier: Programming Language :: Python :: 3.10
16
15
  Classifier: Programming Language :: Python :: 3.11
17
16
  Classifier: Programming Language :: Python :: 3.12
18
17
  Classifier: Programming Language :: Python :: 3.13
19
18
  Classifier: Programming Language :: Python :: Implementation :: CPython
20
19
  Classifier: Programming Language :: Python :: Implementation :: PyPy
21
- Requires-Python: >=3.9
20
+ Requires-Python: >=3.10
22
21
  Requires-Dist: fastembed>=0.4.2
23
- Requires-Dist: haystack-ai>=2.0.1
22
+ Requires-Dist: haystack-ai>=2.22.0
24
23
  Description-Content-Type: text/markdown
25
24
 
26
25
  # fastembed-haystack
@@ -7,7 +7,7 @@ name = "fastembed-haystack"
7
7
  dynamic = ["version"]
8
8
  description = "Haystack 2.x component to embed strings and Documents using fastembed embedding model"
9
9
  readme = "README.md"
10
- requires-python = ">=3.9"
10
+ requires-python = ">=3.10"
11
11
  license = "Apache-2.0"
12
12
  keywords = []
13
13
  authors = [{ name = "deepset GmbH", email = "info@deepset.ai" }]
@@ -15,7 +15,6 @@ 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.9",
19
18
  "Programming Language :: Python :: 3.10",
20
19
  "Programming Language :: Python :: 3.11",
21
20
  "Programming Language :: Python :: 3.12",
@@ -23,7 +22,7 @@ classifiers = [
23
22
  "Programming Language :: Python :: Implementation :: CPython",
24
23
  "Programming Language :: Python :: Implementation :: PyPy",
25
24
  ]
26
- dependencies = ["haystack-ai>=2.0.1", "fastembed>=0.4.2"]
25
+ dependencies = ["haystack-ai>=2.22.0", "fastembed>=0.4.2"]
27
26
 
28
27
  [project.urls]
29
28
  Source = "https://github.com/deepset-ai/haystack-core-integrations"
@@ -75,7 +74,6 @@ check_untyped_defs = true
75
74
  disallow_incomplete_defs = true
76
75
 
77
76
  [tool.ruff]
78
- target-version = "py39"
79
77
  line-length = 120
80
78
 
81
79
  [tool.ruff.lint]
@@ -124,10 +122,6 @@ ignore = [
124
122
  "PLR0913",
125
123
  "PLR0915",
126
124
  ]
127
- unfixable = [
128
- # Don't touch unused imports
129
- "F401",
130
- ]
131
125
 
132
126
  [tool.ruff.lint.isort]
133
127
  known-first-party = ["haystack_integrations"]
@@ -1,4 +1,4 @@
1
- from typing import Any, ClassVar, Optional
1
+ from typing import Any, ClassVar
2
2
 
3
3
  from haystack.dataclasses.sparse_embedding import SparseEmbedding
4
4
  from tqdm import tqdm
@@ -17,8 +17,8 @@ class _FastembedEmbeddingBackendFactory:
17
17
  @staticmethod
18
18
  def get_embedding_backend(
19
19
  model_name: str,
20
- cache_dir: Optional[str] = None,
21
- threads: Optional[int] = None,
20
+ cache_dir: str | None = None,
21
+ threads: int | None = None,
22
22
  local_files_only: bool = False,
23
23
  ) -> "_FastembedEmbeddingBackend":
24
24
  embedding_backend_id = f"{model_name}{cache_dir}{threads}"
@@ -41,8 +41,8 @@ class _FastembedEmbeddingBackend:
41
41
  def __init__(
42
42
  self,
43
43
  model_name: str,
44
- cache_dir: Optional[str] = None,
45
- threads: Optional[int] = None,
44
+ cache_dir: str | None = None,
45
+ threads: int | None = None,
46
46
  local_files_only: bool = False,
47
47
  ):
48
48
  self.model = TextEmbedding(
@@ -70,10 +70,10 @@ class _FastembedSparseEmbeddingBackendFactory:
70
70
  @staticmethod
71
71
  def get_embedding_backend(
72
72
  model_name: str,
73
- cache_dir: Optional[str] = None,
74
- threads: Optional[int] = None,
73
+ cache_dir: str | None = None,
74
+ threads: int | None = None,
75
75
  local_files_only: bool = False,
76
- model_kwargs: Optional[dict[str, Any]] = None,
76
+ model_kwargs: dict[str, Any] | None = None,
77
77
  ) -> "_FastembedSparseEmbeddingBackend":
78
78
  embedding_backend_id = f"{model_name}{cache_dir}{threads}{local_files_only}{model_kwargs}"
79
79
 
@@ -99,10 +99,10 @@ class _FastembedSparseEmbeddingBackend:
99
99
  def __init__(
100
100
  self,
101
101
  model_name: str,
102
- cache_dir: Optional[str] = None,
103
- threads: Optional[int] = None,
102
+ cache_dir: str | None = None,
103
+ threads: int | None = None,
104
104
  local_files_only: bool = False,
105
- model_kwargs: Optional[dict[str, Any]] = None,
105
+ model_kwargs: dict[str, Any] | None = None,
106
106
  ):
107
107
  model_kwargs = model_kwargs or {}
108
108
 
@@ -3,7 +3,7 @@
3
3
  # SPDX-License-Identifier: Apache-2.0
4
4
 
5
5
  from dataclasses import replace
6
- from typing import Any, Optional
6
+ from typing import Any
7
7
 
8
8
  from haystack import Document, component, default_to_dict
9
9
 
@@ -63,15 +63,15 @@ class FastembedDocumentEmbedder:
63
63
  def __init__(
64
64
  self,
65
65
  model: str = "BAAI/bge-small-en-v1.5",
66
- cache_dir: Optional[str] = None,
67
- threads: Optional[int] = None,
66
+ cache_dir: str | None = None,
67
+ threads: int | None = None,
68
68
  prefix: str = "",
69
69
  suffix: str = "",
70
70
  batch_size: int = 256,
71
71
  progress_bar: bool = True,
72
- parallel: Optional[int] = None,
72
+ parallel: int | None = None,
73
73
  local_files_only: bool = False,
74
- meta_fields_to_embed: Optional[list[str]] = None,
74
+ meta_fields_to_embed: list[str] | None = None,
75
75
  embedding_separator: str = "\n",
76
76
  ) -> None:
77
77
  """
@@ -107,7 +107,7 @@ class FastembedDocumentEmbedder:
107
107
  self.local_files_only = local_files_only
108
108
  self.meta_fields_to_embed = meta_fields_to_embed or []
109
109
  self.embedding_separator = embedding_separator
110
- self.embedding_backend: Optional[_FastembedEmbeddingBackend] = None
110
+ self.embedding_backend: _FastembedEmbeddingBackend | None = None
111
111
 
112
112
  def to_dict(self) -> dict[str, Any]:
113
113
  """
@@ -184,7 +184,7 @@ class FastembedDocumentEmbedder:
184
184
  )
185
185
 
186
186
  new_documents = []
187
- for doc, emb in zip(documents, embeddings):
187
+ for doc, emb in zip(documents, embeddings, strict=True):
188
188
  new_documents.append(replace(doc, embedding=emb))
189
189
 
190
190
  return {"documents": new_documents}
@@ -3,7 +3,7 @@
3
3
  # SPDX-License-Identifier: Apache-2.0
4
4
 
5
5
  from dataclasses import replace
6
- from typing import Any, Optional
6
+ from typing import Any
7
7
 
8
8
  from haystack import Document, component, default_to_dict
9
9
 
@@ -62,15 +62,15 @@ class FastembedSparseDocumentEmbedder:
62
62
  def __init__(
63
63
  self,
64
64
  model: str = "prithivida/Splade_PP_en_v1",
65
- cache_dir: Optional[str] = None,
66
- threads: Optional[int] = None,
65
+ cache_dir: str | None = None,
66
+ threads: int | None = None,
67
67
  batch_size: int = 32,
68
68
  progress_bar: bool = True,
69
- parallel: Optional[int] = None,
69
+ parallel: int | None = None,
70
70
  local_files_only: bool = False,
71
- meta_fields_to_embed: Optional[list[str]] = None,
71
+ meta_fields_to_embed: list[str] | None = None,
72
72
  embedding_separator: str = "\n",
73
- model_kwargs: Optional[dict[str, Any]] = None,
73
+ model_kwargs: dict[str, Any] | None = None,
74
74
  ) -> None:
75
75
  """
76
76
  Create an FastembedDocumentEmbedder component.
@@ -103,7 +103,7 @@ class FastembedSparseDocumentEmbedder:
103
103
  self.meta_fields_to_embed = meta_fields_to_embed or []
104
104
  self.embedding_separator = embedding_separator
105
105
  self.model_kwargs = model_kwargs
106
- self.embedding_backend: Optional[_FastembedSparseEmbeddingBackend] = None
106
+ self.embedding_backend: _FastembedSparseEmbeddingBackend | None = None
107
107
 
108
108
  def to_dict(self) -> dict[str, Any]:
109
109
  """
@@ -179,7 +179,7 @@ class FastembedSparseDocumentEmbedder:
179
179
  )
180
180
 
181
181
  new_documents = []
182
- for doc, emb in zip(documents, embeddings):
182
+ for doc, emb in zip(documents, embeddings, strict=True):
183
183
  new_documents.append(replace(doc, sparse_embedding=emb))
184
184
 
185
185
  return {"documents": new_documents}
@@ -2,7 +2,7 @@
2
2
  #
3
3
  # SPDX-License-Identifier: Apache-2.0
4
4
 
5
- from typing import Any, Optional
5
+ from typing import Any
6
6
 
7
7
  from haystack import component, default_to_dict
8
8
  from haystack.dataclasses.sparse_embedding import SparseEmbedding
@@ -37,12 +37,12 @@ class FastembedSparseTextEmbedder:
37
37
  def __init__(
38
38
  self,
39
39
  model: str = "prithivida/Splade_PP_en_v1",
40
- cache_dir: Optional[str] = None,
41
- threads: Optional[int] = None,
40
+ cache_dir: str | None = None,
41
+ threads: int | None = None,
42
42
  progress_bar: bool = True,
43
- parallel: Optional[int] = None,
43
+ parallel: int | None = None,
44
44
  local_files_only: bool = False,
45
- model_kwargs: Optional[dict[str, Any]] = None,
45
+ model_kwargs: dict[str, Any] | None = None,
46
46
  ) -> None:
47
47
  """
48
48
  Create a FastembedSparseTextEmbedder component.
@@ -68,7 +68,7 @@ class FastembedSparseTextEmbedder:
68
68
  self.parallel = parallel
69
69
  self.local_files_only = local_files_only
70
70
  self.model_kwargs = model_kwargs
71
- self.embedding_backend: Optional[_FastembedSparseEmbeddingBackend] = None
71
+ self.embedding_backend: _FastembedSparseEmbeddingBackend | None = None
72
72
 
73
73
  def to_dict(self) -> dict[str, Any]:
74
74
  """
@@ -2,7 +2,7 @@
2
2
  #
3
3
  # SPDX-License-Identifier: Apache-2.0
4
4
 
5
- from typing import Any, Optional
5
+ from typing import Any
6
6
 
7
7
  from haystack import component, default_to_dict
8
8
 
@@ -33,12 +33,12 @@ class FastembedTextEmbedder:
33
33
  def __init__(
34
34
  self,
35
35
  model: str = "BAAI/bge-small-en-v1.5",
36
- cache_dir: Optional[str] = None,
37
- threads: Optional[int] = None,
36
+ cache_dir: str | None = None,
37
+ threads: int | None = None,
38
38
  prefix: str = "",
39
39
  suffix: str = "",
40
40
  progress_bar: bool = True,
41
- parallel: Optional[int] = None,
41
+ parallel: int | None = None,
42
42
  local_files_only: bool = False,
43
43
  ) -> None:
44
44
  """
@@ -67,7 +67,7 @@ class FastembedTextEmbedder:
67
67
  self.progress_bar = progress_bar
68
68
  self.parallel = parallel
69
69
  self.local_files_only = local_files_only
70
- self.embedding_backend: Optional[_FastembedEmbeddingBackend] = None
70
+ self.embedding_backend: _FastembedEmbeddingBackend | None = None
71
71
 
72
72
  def to_dict(self) -> dict[str, Any]:
73
73
  """
@@ -2,7 +2,7 @@
2
2
  #
3
3
  # SPDX-License-Identifier: Apache-2.0
4
4
 
5
- from typing import Any, Optional
5
+ from typing import Any
6
6
 
7
7
  from haystack import Document, component, default_from_dict, default_to_dict, logging
8
8
 
@@ -39,12 +39,12 @@ class FastembedRanker:
39
39
  self,
40
40
  model_name: str = "Xenova/ms-marco-MiniLM-L-6-v2",
41
41
  top_k: int = 10,
42
- cache_dir: Optional[str] = None,
43
- threads: Optional[int] = None,
42
+ cache_dir: str | None = None,
43
+ threads: int | None = None,
44
44
  batch_size: int = 64,
45
- parallel: Optional[int] = None,
45
+ parallel: int | None = None,
46
46
  local_files_only: bool = False,
47
- meta_fields_to_embed: Optional[list[str]] = None,
47
+ meta_fields_to_embed: list[str] | None = None,
48
48
  meta_data_separator: str = "\n",
49
49
  ):
50
50
  """
@@ -80,7 +80,7 @@ class FastembedRanker:
80
80
  self.local_files_only = local_files_only
81
81
  self.meta_fields_to_embed = meta_fields_to_embed or []
82
82
  self.meta_data_separator = meta_data_separator
83
- self._model: Optional[TextCrossEncoder] = None
83
+ self._model: TextCrossEncoder | None = None
84
84
 
85
85
  def to_dict(self) -> dict[str, Any]:
86
86
  """
@@ -144,7 +144,7 @@ class FastembedRanker:
144
144
  return concatenated_input_list
145
145
 
146
146
  @component.output_types(documents=list[Document])
147
- def run(self, query: str, documents: list[Document], top_k: Optional[int] = None) -> dict[str, list[Document]]:
147
+ def run(self, query: str, documents: list[Document], top_k: int | None = None) -> dict[str, list[Document]]:
148
148
  """
149
149
  Returns a list of documents ranked by their similarity to the given query, using FastEmbed.
150
150
 
@@ -192,7 +192,7 @@ class FastembedRanker:
192
192
  )
193
193
 
194
194
  # Combine the two lists into a single list of tuples
195
- doc_scores = list(zip(documents, scores))
195
+ doc_scores = list(zip(documents, scores, strict=True))
196
196
 
197
197
  # Sort the list of tuples by the score in descending order
198
198
  sorted_doc_scores = sorted(doc_scores, key=lambda x: x[1], reverse=True)
@@ -262,6 +262,7 @@ class TestFastembedDocumentEmbedder:
262
262
  embedding_separator="\n",
263
263
  )
264
264
  embedder.embedding_backend = MagicMock()
265
+ embedder.embedding_backend.embed.return_value = [np.random.rand(3, 16).tolist() for _ in range(5)]
265
266
 
266
267
  documents = [Document(content=f"document-number {i}", meta={"meta_field": f"meta_value {i}"}) for i in range(5)]
267
268
 
@@ -4,6 +4,7 @@
4
4
 
5
5
  from unittest.mock import MagicMock
6
6
 
7
+ import numpy as np
7
8
  import pytest
8
9
  from haystack import Document, default_from_dict
9
10
 
@@ -237,6 +238,7 @@ class TestFastembedRanker:
237
238
  meta_fields_to_embed=["meta_field"],
238
239
  )
239
240
  ranker._model = MagicMock()
241
+ ranker._model.rerank.return_value = [np.random.rand(3, 16).tolist() for _ in range(5)]
240
242
 
241
243
  documents = [Document(content=f"document-number {i}", meta={"meta_field": f"meta_value {i}"}) for i in range(5)]
242
244
  query = "test"
@@ -267,7 +267,7 @@ class TestFastembedSparseDocumentEmbedderDoc:
267
267
  embedding_separator="\n",
268
268
  )
269
269
  embedder.embedding_backend = MagicMock()
270
-
270
+ embedder.embedding_backend.embed.return_value = [self._generate_mocked_sparse_embedding(3) for _ in range(5)]
271
271
  documents = [Document(content=f"document-number {i}", meta={"meta_field": f"meta_value {i}"}) for i in range(5)]
272
272
 
273
273
  embedder.run(documents=documents)