chroma-haystack 3.1.0__tar.gz → 3.3.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 (59) hide show
  1. {chroma_haystack-3.1.0 → chroma_haystack-3.3.0}/CHANGELOG.md +12 -0
  2. {chroma_haystack-3.1.0 → chroma_haystack-3.3.0}/PKG-INFO +1 -1
  3. {chroma_haystack-3.1.0 → chroma_haystack-3.3.0}/pyproject.toml +26 -37
  4. {chroma_haystack-3.1.0 → chroma_haystack-3.3.0}/src/haystack_integrations/components/retrievers/chroma/retriever.py +113 -3
  5. chroma_haystack-3.3.0/src/haystack_integrations/components/retrievers/py.typed +0 -0
  6. {chroma_haystack-3.1.0 → chroma_haystack-3.3.0}/src/haystack_integrations/document_stores/chroma/document_store.py +317 -164
  7. {chroma_haystack-3.1.0 → chroma_haystack-3.3.0}/src/haystack_integrations/document_stores/chroma/filters.py +3 -3
  8. {chroma_haystack-3.1.0 → chroma_haystack-3.3.0}/src/haystack_integrations/document_stores/chroma/utils.py +3 -1
  9. chroma_haystack-3.3.0/src/haystack_integrations/document_stores/py.typed +0 -0
  10. chroma_haystack-3.3.0/tests/conftest.py +102 -0
  11. {chroma_haystack-3.1.0 → chroma_haystack-3.3.0}/tests/test_document_store.py +85 -173
  12. chroma_haystack-3.3.0/tests/test_document_store_async.py +122 -0
  13. chroma_haystack-3.3.0/tests/test_retriever.py +165 -0
  14. chroma_haystack-3.1.0/tests/test_retriever.py +0 -108
  15. {chroma_haystack-3.1.0 → chroma_haystack-3.3.0}/.gitignore +0 -0
  16. {chroma_haystack-3.1.0 → chroma_haystack-3.3.0}/LICENSE +0 -0
  17. {chroma_haystack-3.1.0 → chroma_haystack-3.3.0}/README.md +0 -0
  18. {chroma_haystack-3.1.0 → chroma_haystack-3.3.0}/example/data/usr_01.txt +0 -0
  19. {chroma_haystack-3.1.0 → chroma_haystack-3.3.0}/example/data/usr_02.txt +0 -0
  20. {chroma_haystack-3.1.0 → chroma_haystack-3.3.0}/example/data/usr_03.txt +0 -0
  21. {chroma_haystack-3.1.0 → chroma_haystack-3.3.0}/example/data/usr_04.txt +0 -0
  22. {chroma_haystack-3.1.0 → chroma_haystack-3.3.0}/example/data/usr_05.txt +0 -0
  23. {chroma_haystack-3.1.0 → chroma_haystack-3.3.0}/example/data/usr_06.txt +0 -0
  24. {chroma_haystack-3.1.0 → chroma_haystack-3.3.0}/example/data/usr_07.txt +0 -0
  25. {chroma_haystack-3.1.0 → chroma_haystack-3.3.0}/example/data/usr_08.txt +0 -0
  26. {chroma_haystack-3.1.0 → chroma_haystack-3.3.0}/example/data/usr_09.txt +0 -0
  27. {chroma_haystack-3.1.0 → chroma_haystack-3.3.0}/example/data/usr_10.txt +0 -0
  28. {chroma_haystack-3.1.0 → chroma_haystack-3.3.0}/example/data/usr_11.txt +0 -0
  29. {chroma_haystack-3.1.0 → chroma_haystack-3.3.0}/example/data/usr_12.txt +0 -0
  30. {chroma_haystack-3.1.0 → chroma_haystack-3.3.0}/example/data/usr_20.txt +0 -0
  31. {chroma_haystack-3.1.0 → chroma_haystack-3.3.0}/example/data/usr_21.txt +0 -0
  32. {chroma_haystack-3.1.0 → chroma_haystack-3.3.0}/example/data/usr_22.txt +0 -0
  33. {chroma_haystack-3.1.0 → chroma_haystack-3.3.0}/example/data/usr_23.txt +0 -0
  34. {chroma_haystack-3.1.0 → chroma_haystack-3.3.0}/example/data/usr_24.txt +0 -0
  35. {chroma_haystack-3.1.0 → chroma_haystack-3.3.0}/example/data/usr_25.txt +0 -0
  36. {chroma_haystack-3.1.0 → chroma_haystack-3.3.0}/example/data/usr_26.txt +0 -0
  37. {chroma_haystack-3.1.0 → chroma_haystack-3.3.0}/example/data/usr_27.txt +0 -0
  38. {chroma_haystack-3.1.0 → chroma_haystack-3.3.0}/example/data/usr_28.txt +0 -0
  39. {chroma_haystack-3.1.0 → chroma_haystack-3.3.0}/example/data/usr_29.txt +0 -0
  40. {chroma_haystack-3.1.0 → chroma_haystack-3.3.0}/example/data/usr_30.txt +0 -0
  41. {chroma_haystack-3.1.0 → chroma_haystack-3.3.0}/example/data/usr_31.txt +0 -0
  42. {chroma_haystack-3.1.0 → chroma_haystack-3.3.0}/example/data/usr_32.txt +0 -0
  43. {chroma_haystack-3.1.0 → chroma_haystack-3.3.0}/example/data/usr_40.txt +0 -0
  44. {chroma_haystack-3.1.0 → chroma_haystack-3.3.0}/example/data/usr_41.txt +0 -0
  45. {chroma_haystack-3.1.0 → chroma_haystack-3.3.0}/example/data/usr_42.txt +0 -0
  46. {chroma_haystack-3.1.0 → chroma_haystack-3.3.0}/example/data/usr_43.txt +0 -0
  47. {chroma_haystack-3.1.0 → chroma_haystack-3.3.0}/example/data/usr_44.txt +0 -0
  48. {chroma_haystack-3.1.0 → chroma_haystack-3.3.0}/example/data/usr_45.txt +0 -0
  49. {chroma_haystack-3.1.0 → chroma_haystack-3.3.0}/example/data/usr_46.txt +0 -0
  50. {chroma_haystack-3.1.0 → chroma_haystack-3.3.0}/example/data/usr_50.txt +0 -0
  51. {chroma_haystack-3.1.0 → chroma_haystack-3.3.0}/example/data/usr_51.txt +0 -0
  52. {chroma_haystack-3.1.0 → chroma_haystack-3.3.0}/example/data/usr_52.txt +0 -0
  53. {chroma_haystack-3.1.0 → chroma_haystack-3.3.0}/example/data/usr_90.txt +0 -0
  54. {chroma_haystack-3.1.0 → chroma_haystack-3.3.0}/example/example.py +0 -0
  55. {chroma_haystack-3.1.0 → chroma_haystack-3.3.0}/pydoc/config.yml +0 -0
  56. {chroma_haystack-3.1.0 → chroma_haystack-3.3.0}/src/haystack_integrations/components/retrievers/chroma/__init__.py +0 -0
  57. {chroma_haystack-3.1.0 → chroma_haystack-3.3.0}/src/haystack_integrations/document_stores/chroma/__init__.py +0 -0
  58. {chroma_haystack-3.1.0 → chroma_haystack-3.3.0}/src/haystack_integrations/document_stores/chroma/errors.py +0 -0
  59. {chroma_haystack-3.1.0 → chroma_haystack-3.3.0}/tests/__init__.py +0 -0
@@ -1,5 +1,17 @@
1
1
  # Changelog
2
2
 
3
+ ## [integrations/chroma-v3.2.0] - 2025-06-06
4
+
5
+ ### 🚀 Features
6
+
7
+ - Add async support for Chroma + improve typing (#1697)
8
+
9
+
10
+ ### 🧹 Chores
11
+
12
+ - Align core-integrations Hatch scripts (#1898)
13
+
14
+
3
15
  ## [integrations/chroma-v2.0.3] - 2025-04-04
4
16
 
5
17
  ### 🐛 Bug Fixes
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: chroma-haystack
3
- Version: 3.1.0
3
+ Version: 3.3.0
4
4
  Project-URL: Documentation, https://github.com/deepset-ai/haystack-core-integrations/tree/main/integrations/chroma#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/chroma
@@ -43,37 +43,36 @@ git_describe_command = 'git describe --tags --match="integrations/chroma-v[0-9]*
43
43
 
44
44
  [tool.hatch.envs.default]
45
45
  installer = "uv"
46
- dependencies = [
47
- "coverage[toml]>=6.5",
48
- "pytest",
49
- "pytest-rerunfailures",
50
- "haystack-pydoc-tools",
51
- "databind-core<4.5.0", # FIXME: the latest 4.5.0 causes loops in pip resolver
52
- ]
46
+ dependencies = ["haystack-pydoc-tools", "ruff"]
47
+
53
48
  [tool.hatch.envs.default.scripts]
54
- test = "pytest {args:tests}"
55
- test-cov = "coverage run -m pytest {args:tests}"
56
- test-cov-retry = "test-cov --reruns 3 --reruns-delay 30 -x"
57
- cov-report = ["- coverage combine", "coverage report"]
58
- cov = ["test-cov", "cov-report"]
59
- cov-retry = ["test-cov-retry", "cov-report"]
60
49
  docs = ["pydoc-markdown pydoc/config.yml"]
50
+ fmt = "ruff check --fix {args} && ruff format {args}"
51
+ fmt-check = "ruff check {args} && ruff format --check {args}"
61
52
 
62
- [tool.hatch.envs.lint]
63
- installer = "uv"
64
- detached = true
53
+ [tool.hatch.envs.test]
65
54
  dependencies = [
66
- "pip",
67
- "black>=23.1.0",
68
- "mypy>=1.0.0",
69
- "ruff>=0.0.243",
70
- "numpy", # we need the stubs from the main package
55
+ "pytest",
56
+ "pytest-asyncio",
57
+ "pytest-cov",
58
+ "pytest-rerunfailures",
59
+ "mypy",
60
+ "pip"
71
61
  ]
72
- [tool.hatch.envs.lint.scripts]
73
- typing = "mypy --install-types --non-interactive --explicit-package-bases {args:src/ tests}"
74
- style = ["ruff check {args:.}", "black --check --diff {args:.}"]
75
- fmt = ["black {args:.}", "ruff check --fix {args:.}", "style"]
76
- all = ["style", "typing"]
62
+
63
+ [tool.hatch.envs.test.scripts]
64
+ unit = 'pytest -m "not integration" {args:tests}'
65
+ integration = 'pytest -m "integration" {args:tests}'
66
+ all = 'pytest {args:tests}'
67
+ cov-retry = 'all --cov=haystack_integrations --reruns 3 --reruns-delay 30 -x'
68
+
69
+ types = "mypy -p haystack_integrations.components.retrievers.chroma -p haystack_integrations.document_stores.chroma {args}"
70
+
71
+ [tool.mypy]
72
+ install_types = true
73
+ non_interactive = true
74
+ check_untyped_defs = true
75
+ disallow_incomplete_defs = true
77
76
 
78
77
  [tool.hatch.metadata]
79
78
  allow-direct-references = true
@@ -166,14 +165,4 @@ exclude_lines = ["no cov", "if __name__ == .__main__.:", "if TYPE_CHECKING:"]
166
165
 
167
166
  [tool.pytest.ini_options]
168
167
  minversion = "6.0"
169
- markers = ["unit: unit tests", "integration: integration tests"]
170
-
171
- [[tool.mypy.overrides]]
172
- module = [
173
- "chromadb.*",
174
- "haystack.*",
175
- "haystack_integrations.*",
176
- "pytest.*",
177
- "numpy.*",
178
- ]
179
- ignore_missing_imports = true
168
+ markers = ["integration: integration tests"]
@@ -71,7 +71,7 @@ class ChromaQueryTextRetriever:
71
71
  query: str,
72
72
  filters: Optional[Dict[str, Any]] = None,
73
73
  top_k: Optional[int] = None,
74
- ):
74
+ ) -> Dict[str, Any]:
75
75
  """
76
76
  Run the retriever on the given input data.
77
77
 
@@ -90,6 +90,33 @@ class ChromaQueryTextRetriever:
90
90
  top_k = top_k or self.top_k
91
91
  return {"documents": self.document_store.search([query], top_k, filters)[0]}
92
92
 
93
+ @component.output_types(documents=List[Document])
94
+ async def run_async(
95
+ self,
96
+ query: str,
97
+ filters: Optional[Dict[str, Any]] = None,
98
+ top_k: Optional[int] = None,
99
+ ) -> Dict[str, Any]:
100
+ """
101
+ Asynchronously run the retriever on the given input data.
102
+
103
+ Asynchronous methods are only supported for HTTP connections.
104
+
105
+ :param query: The input data for the retriever. In this case, a plain-text query.
106
+ :param filters: Filters applied to the retrieved Documents. The way runtime filters are applied depends on
107
+ the `filter_policy` chosen at retriever initialization. See init method docstring for more
108
+ details.
109
+ :param top_k: The maximum number of documents to retrieve.
110
+ If not specified, the default value from the constructor is used.
111
+ :returns: A dictionary with the following keys:
112
+ - `documents`: List of documents returned by the search engine.
113
+
114
+ :raises ValueError: If the specified document store is not found or is not a MemoryDocumentStore instance.
115
+ """
116
+ filters = apply_filter_policy(self.filter_policy, self.filters, filters)
117
+ top_k = top_k or self.top_k
118
+ return {"documents": (await self.document_store.search_async([query], top_k, filters))[0]}
119
+
93
120
  @classmethod
94
121
  def from_dict(cls, data: Dict[str, Any]) -> "ChromaQueryTextRetriever":
95
122
  """
@@ -126,18 +153,38 @@ class ChromaQueryTextRetriever:
126
153
 
127
154
 
128
155
  @component
129
- class ChromaEmbeddingRetriever(ChromaQueryTextRetriever):
156
+ class ChromaEmbeddingRetriever:
130
157
  """
131
158
  A component for retrieving documents from a [Chroma database](https://docs.trychroma.com/) using embeddings.
132
159
  """
133
160
 
161
+ def __init__(
162
+ self,
163
+ document_store: ChromaDocumentStore,
164
+ filters: Optional[Dict[str, Any]] = None,
165
+ top_k: int = 10,
166
+ filter_policy: Union[str, FilterPolicy] = FilterPolicy.REPLACE,
167
+ ):
168
+ """
169
+ :param document_store: an instance of `ChromaDocumentStore`.
170
+ :param filters: filters to narrow down the search space.
171
+ :param top_k: the maximum number of documents to retrieve.
172
+ :param filter_policy: Policy to determine how filters are applied.
173
+ """
174
+ self.filters = filters or {}
175
+ self.top_k = top_k
176
+ self.document_store = document_store
177
+ self.filter_policy = (
178
+ filter_policy if isinstance(filter_policy, FilterPolicy) else FilterPolicy.from_str(filter_policy)
179
+ )
180
+
134
181
  @component.output_types(documents=List[Document])
135
182
  def run(
136
183
  self,
137
184
  query_embedding: List[float],
138
185
  filters: Optional[Dict[str, Any]] = None,
139
186
  top_k: Optional[int] = None,
140
- ):
187
+ ) -> Dict[str, Any]:
141
188
  """
142
189
  Run the retriever on the given input data.
143
190
 
@@ -157,3 +204,66 @@ class ChromaEmbeddingRetriever(ChromaQueryTextRetriever):
157
204
 
158
205
  query_embeddings = [query_embedding]
159
206
  return {"documents": self.document_store.search_embeddings(query_embeddings, top_k, filters)[0]}
207
+
208
+ @component.output_types(documents=List[Document])
209
+ async def run_async(
210
+ self,
211
+ query_embedding: List[float],
212
+ filters: Optional[Dict[str, Any]] = None,
213
+ top_k: Optional[int] = None,
214
+ ) -> Dict[str, Any]:
215
+ """
216
+ Asynchronously run the retriever on the given input data.
217
+
218
+ Asynchronous methods are only supported for HTTP connections.
219
+
220
+ :param query_embedding: the query embeddings.
221
+ :param filters: Filters applied to the retrieved Documents. The way runtime filters are applied depends on
222
+ the `filter_policy` chosen at retriever initialization. See init method docstring for more
223
+ details.
224
+ :param top_k: the maximum number of documents to retrieve.
225
+ If not specified, the default value from the constructor is used.
226
+
227
+ :returns: a dictionary with the following keys:
228
+ - `documents`: List of documents returned by the search engine.
229
+ """
230
+ filters = apply_filter_policy(self.filter_policy, self.filters, filters)
231
+
232
+ top_k = top_k or self.top_k
233
+
234
+ query_embeddings = [query_embedding]
235
+ return {"documents": (await self.document_store.search_embeddings_async(query_embeddings, top_k, filters))[0]}
236
+
237
+ @classmethod
238
+ def from_dict(cls, data: Dict[str, Any]) -> "ChromaEmbeddingRetriever":
239
+ """
240
+ Deserializes the component from a dictionary.
241
+
242
+ :param data:
243
+ Dictionary to deserialize from.
244
+ :returns:
245
+ Deserialized component.
246
+ """
247
+ document_store = ChromaDocumentStore.from_dict(data["init_parameters"]["document_store"])
248
+ data["init_parameters"]["document_store"] = document_store
249
+ # Pipelines serialized with old versions of the component might not
250
+ # have the filter_policy field.
251
+ if filter_policy := data["init_parameters"].get("filter_policy"):
252
+ data["init_parameters"]["filter_policy"] = FilterPolicy.from_str(filter_policy)
253
+
254
+ return default_from_dict(cls, data)
255
+
256
+ def to_dict(self) -> Dict[str, Any]:
257
+ """
258
+ Serializes the component to a dictionary.
259
+
260
+ :returns:
261
+ Dictionary with serialized data.
262
+ """
263
+ return default_to_dict(
264
+ self,
265
+ filters=self.filters,
266
+ top_k=self.top_k,
267
+ filter_policy=self.filter_policy.value,
268
+ document_store=self.document_store.to_dict(),
269
+ )