qdrant-haystack 8.0.0__tar.gz → 8.1.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.

Potentially problematic release.


This version of qdrant-haystack might be problematic. Click here for more details.

Files changed (22) hide show
  1. {qdrant_haystack-8.0.0 → qdrant_haystack-8.1.0}/CHANGELOG.md +76 -12
  2. {qdrant_haystack-8.0.0 → qdrant_haystack-8.1.0}/PKG-INFO +3 -3
  3. {qdrant_haystack-8.0.0 → qdrant_haystack-8.1.0}/pyproject.toml +3 -3
  4. {qdrant_haystack-8.0.0 → qdrant_haystack-8.1.0}/src/haystack_integrations/document_stores/qdrant/document_store.py +15 -7
  5. {qdrant_haystack-8.0.0 → qdrant_haystack-8.1.0}/tests/test_document_store.py +78 -1
  6. {qdrant_haystack-8.0.0 → qdrant_haystack-8.1.0}/.gitignore +0 -0
  7. {qdrant_haystack-8.0.0 → qdrant_haystack-8.1.0}/LICENSE.txt +0 -0
  8. {qdrant_haystack-8.0.0 → qdrant_haystack-8.1.0}/README.md +0 -0
  9. {qdrant_haystack-8.0.0 → qdrant_haystack-8.1.0}/examples/embedding_retrieval.py +0 -0
  10. {qdrant_haystack-8.0.0 → qdrant_haystack-8.1.0}/pydoc/config.yml +0 -0
  11. {qdrant_haystack-8.0.0 → qdrant_haystack-8.1.0}/src/haystack_integrations/components/retrievers/qdrant/__init__.py +0 -0
  12. {qdrant_haystack-8.0.0 → qdrant_haystack-8.1.0}/src/haystack_integrations/components/retrievers/qdrant/retriever.py +0 -0
  13. {qdrant_haystack-8.0.0 → qdrant_haystack-8.1.0}/src/haystack_integrations/document_stores/qdrant/__init__.py +0 -0
  14. {qdrant_haystack-8.0.0 → qdrant_haystack-8.1.0}/src/haystack_integrations/document_stores/qdrant/converters.py +0 -0
  15. {qdrant_haystack-8.0.0 → qdrant_haystack-8.1.0}/src/haystack_integrations/document_stores/qdrant/filters.py +0 -0
  16. {qdrant_haystack-8.0.0 → qdrant_haystack-8.1.0}/src/haystack_integrations/document_stores/qdrant/migrate_to_sparse.py +0 -0
  17. {qdrant_haystack-8.0.0 → qdrant_haystack-8.1.0}/tests/__init__.py +0 -0
  18. {qdrant_haystack-8.0.0 → qdrant_haystack-8.1.0}/tests/conftest.py +0 -0
  19. {qdrant_haystack-8.0.0 → qdrant_haystack-8.1.0}/tests/test_converters.py +0 -0
  20. {qdrant_haystack-8.0.0 → qdrant_haystack-8.1.0}/tests/test_dict_converters.py +0 -0
  21. {qdrant_haystack-8.0.0 → qdrant_haystack-8.1.0}/tests/test_filters.py +0 -0
  22. {qdrant_haystack-8.0.0 → qdrant_haystack-8.1.0}/tests/test_retriever.py +0 -0
@@ -1,22 +1,47 @@
1
1
  # Changelog
2
2
 
3
+ ## [integrations/qdrant-v8.0.0] - 2025-02-19
4
+
5
+ ### 🧹 Chores
6
+
7
+ - Fix linting/isort (#1215)
8
+ - Inherit from `FilterDocumentsTestWithDataframe` in Document Stores (#1290)
9
+ - [**breaking**] Qdrant - remove dataframe support (#1403)
10
+
11
+
3
12
  ## [integrations/qdrant-v7.0.0] - 2024-10-29
4
13
 
5
- ### ⚙️ Miscellaneous Tasks
14
+ ### ⚙️ CI
6
15
 
7
- - Update ruff linting scripts and settings (#1105)
8
16
  - Adopt uv as installer (#1142)
9
17
 
18
+ ### 🧹 Chores
19
+
20
+ - Update ruff linting scripts and settings (#1105)
21
+
22
+ ### 🌀 Miscellaneous
23
+
24
+ - Refactor!: Qdrant - remove `index` parameter from methods (#1160)
25
+
10
26
  ## [integrations/qdrant-v6.0.0] - 2024-09-13
11
27
 
28
+ ### 🌀 Miscellaneous
29
+
30
+ - Remove support for deprecated legacy filters in Qdrant (#1084)
31
+
12
32
  ## [integrations/qdrant-v5.1.0] - 2024-09-12
13
33
 
14
34
  ### 🚀 Features
15
35
 
16
36
  - Qdrant - Add group_by and group_size optional parameters to Retrievers (#1054)
17
37
 
38
+
18
39
  ## [integrations/qdrant-v5.0.0] - 2024-09-02
19
40
 
41
+ ### 🌀 Miscellaneous
42
+
43
+ - Fix!: fix type errors in `QdrantDocumentStore`; rename `ids` (parameter of `delete_documents`) to `document_ids` (#1041)
44
+
20
45
  ## [integrations/qdrant-v4.2.0] - 2024-08-27
21
46
 
22
47
  ### 🚜 Refactor
@@ -27,12 +52,18 @@
27
52
 
28
53
  - Do not retry tests in `hatch run test` command (#954)
29
54
 
55
+ ### 🌀 Miscellaneous
56
+
57
+ - Chore: Update Qdrant tests for the new `apply_filter_policy` usage (#969)
58
+ - Chore: qdrant - ruff update, don't ruff tests (#989)
59
+
30
60
  ## [integrations/qdrant-v4.1.2] - 2024-07-15
31
61
 
32
62
  ### 🐛 Bug Fixes
33
63
 
34
64
  - `qdrant` - Fallback to default filter policy when deserializing retrievers without the init parameter (#902)
35
65
 
66
+
36
67
  ## [integrations/qdrant-v4.1.1] - 2024-07-10
37
68
 
38
69
  ### 🚀 Features
@@ -43,6 +74,10 @@
43
74
 
44
75
  - Errors in convert_filters_to_qdrant (#870)
45
76
 
77
+ ### 🌀 Miscellaneous
78
+
79
+ - Chore: Minor retriever pydoc fix (#884)
80
+
46
81
  ## [integrations/qdrant-v4.1.0] - 2024-07-03
47
82
 
48
83
  ### 🚀 Features
@@ -50,6 +85,7 @@
50
85
  - Add `score_threshold` to Qdrant Retrievers (#860)
51
86
  - Qdrant - add support for BM42 (#864)
52
87
 
88
+
53
89
  ## [integrations/qdrant-v4.0.0] - 2024-07-02
54
90
 
55
91
  ### 🚜 Refactor
@@ -57,17 +93,25 @@
57
93
  - [**breaking**] Qdrant - remove unused init parameters: `content_field`, `name_field`, `embedding_field`, and `duplicate_documents` (#861)
58
94
  - [**breaking**] Qdrant - set `scale_score` default value to `False` (#862)
59
95
 
60
- ### ⚙️ Miscellaneous Tasks
96
+ ### ⚙️ CI
61
97
 
62
98
  - Retry tests to reduce flakyness (#836)
99
+
100
+ ### 🧹 Chores
101
+
63
102
  - Update ruff invocation to include check parameter (#853)
64
103
 
104
+ ### 🌀 Miscellaneous
105
+
106
+ - Ci: install `pytest-rerunfailures` where needed; add retry config to `test-cov` script (#845)
107
+
65
108
  ## [integrations/qdrant-v3.8.1] - 2024-06-20
66
109
 
67
110
  ### 📚 Documentation
68
111
 
69
112
  - Added docstrings for QdrantDocumentStore (#808)
70
113
 
114
+
71
115
  ## [integrations/qdrant-v3.8.0] - 2024-06-06
72
116
 
73
117
  ### 🚀 Features
@@ -86,17 +130,29 @@
86
130
 
87
131
  - Defer database connection to the first usage (#748)
88
132
 
133
+ ### 🌀 Miscellaneous
134
+
135
+ - Qdrant - improve docstrings for retrievers (#687)
136
+ - Chore: change the pydoc renderer class (#718)
137
+ - Allow vanilla qdrant filters (#692)
138
+
89
139
  ## [integrations/qdrant-v3.5.0] - 2024-04-24
90
140
 
141
+ ### 🌀 Miscellaneous
142
+
143
+ - Chore: add license classifiers (#680)
144
+ - Qdrant - add hybrid retriever (#675)
145
+
91
146
  ## [integrations/qdrant-v3.4.0] - 2024-04-23
92
147
 
93
- ### Qdrant
148
+ ### 🌀 Miscellaneous
94
149
 
95
150
  - Add embedding retrieval example (#666)
151
+ - Rename `QdrantSparseRetriever` to `QdrantSparseEmbeddingRetriever` (#681)
96
152
 
97
153
  ## [integrations/qdrant-v3.3.1] - 2024-04-12
98
154
 
99
- ### Qdrant
155
+ ### 🌀 Miscellaneous
100
156
 
101
157
  - Add migration utility function for Sparse Embedding support (#659)
102
158
 
@@ -110,7 +166,7 @@
110
166
 
111
167
  ### 🐛 Bug Fixes
112
168
 
113
- - Fix haystack-ai pin (#649)
169
+ - Fix `haystack-ai` pins (#649)
114
170
 
115
171
  ## [integrations/qdrant-v3.2.0] - 2024-03-27
116
172
 
@@ -121,11 +177,9 @@
121
177
 
122
178
  ### 🐛 Bug Fixes
123
179
 
124
- - Fix linter errors (#282)
180
+ - Fix: fix linter errors (#282)
125
181
  - Fix order of API docs (#447)
126
-
127
- This PR will also push the docs to Readme
128
- - Fixes (#518)
182
+ - Doc: fixing docstrings for qdrant (#518)
129
183
 
130
184
  ### 🚜 Refactor
131
185
 
@@ -137,13 +191,19 @@ This PR will also push the docs to Readme
137
191
  - Small consistency improvements (#536)
138
192
  - Disable-class-def (#556)
139
193
 
140
- ### ⚙️ Miscellaneous Tasks
194
+ ### ⚙️ CI
141
195
 
142
196
  - Generate API docs for Qdrant (#361)
143
197
 
198
+ ### 🌀 Miscellaneous
199
+
200
+ - Make tests show coverage (#566)
201
+ - Remove references to Python 3.7 (#601)
202
+ - Make Document Stores initially skip `SparseEmbedding` (#606)
203
+
144
204
  ## [integrations/qdrant-v3.0.0] - 2024-01-22
145
205
 
146
- ### Refact
206
+ ### 🌀 Miscellaneous
147
207
 
148
208
  - [**breaking**] Change import paths (#255)
149
209
 
@@ -161,4 +221,8 @@ This PR will also push the docs to Readme
161
221
 
162
222
  - Use `hatch_vcs` to manage integrations versioning (#103)
163
223
 
224
+ ### 🌀 Miscellaneous
225
+
226
+ - Renamed QdrntRetriever to QdrntEmbeddingRetriever (#174)
227
+
164
228
  <!-- generated by git-cliff -->
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: qdrant-haystack
3
- Version: 8.0.0
3
+ Version: 8.1.0
4
4
  Summary: An integration of Qdrant ANN vector database backend with Haystack
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/qdrant/README.md
@@ -11,13 +11,13 @@ 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.8
15
14
  Classifier: Programming Language :: Python :: 3.9
16
15
  Classifier: Programming Language :: Python :: 3.10
17
16
  Classifier: Programming Language :: Python :: 3.11
17
+ Classifier: Programming Language :: Python :: 3.12
18
18
  Classifier: Programming Language :: Python :: Implementation :: CPython
19
19
  Classifier: Programming Language :: Python :: Implementation :: PyPy
20
- Requires-Python: >=3.8
20
+ Requires-Python: >=3.9
21
21
  Requires-Dist: haystack-ai
22
22
  Requires-Dist: qdrant-client>=1.10.0
23
23
  Description-Content-Type: text/markdown
@@ -7,7 +7,7 @@ name = "qdrant-haystack"
7
7
  dynamic = ["version"]
8
8
  description = 'An integration of Qdrant ANN vector database backend with Haystack'
9
9
  readme = "README.md"
10
- requires-python = ">=3.8"
10
+ requires-python = ">=3.9"
11
11
  license = "Apache-2.0"
12
12
  keywords = []
13
13
  authors = [
@@ -18,10 +18,10 @@ classifiers = [
18
18
  "License :: OSI Approved :: Apache Software License",
19
19
  "Development Status :: 4 - Beta",
20
20
  "Programming Language :: Python",
21
- "Programming Language :: Python :: 3.8",
22
21
  "Programming Language :: Python :: 3.9",
23
22
  "Programming Language :: Python :: 3.10",
24
23
  "Programming Language :: Python :: 3.11",
24
+ "Programming Language :: Python :: 3.12",
25
25
  "Programming Language :: Python :: Implementation :: CPython",
26
26
  "Programming Language :: Python :: Implementation :: PyPy",
27
27
  ]
@@ -56,7 +56,7 @@ cov-retry = ["test-cov-retry", "cov-report"]
56
56
  docs = ["pydoc-markdown pydoc/config.yml"]
57
57
 
58
58
  [[tool.hatch.envs.all.matrix]]
59
- python = ["3.8", "3.9", "3.10", "3.11"]
59
+ python = [ "3.9", "3.10", "3.11"]
60
60
 
61
61
  [tool.hatch.envs.lint]
62
62
  installer = "uv"
@@ -48,8 +48,8 @@ def get_batches_from_generator(iterable, n):
48
48
 
49
49
  class QdrantDocumentStore:
50
50
  """
51
- QdrantDocumentStore is a Document Store for Qdrant.
52
- It can be used with any Qdrant instance: in-memory, disk-persisted, Docker-based,
51
+ A QdrantDocumentStore implementation that you
52
+ can use with any Qdrant instance: in-memory, disk-persisted, Docker-based,
53
53
  and Qdrant Cloud Cluster deployments.
54
54
 
55
55
  Usage example by creating an in-memory instance:
@@ -866,10 +866,18 @@ class QdrantDocumentStore:
866
866
 
867
867
  collection_info = self.client.get_collection(collection_name)
868
868
 
869
- has_named_vectors = (
870
- isinstance(collection_info.config.params.vectors, dict)
871
- and DENSE_VECTORS_NAME in collection_info.config.params.vectors
872
- )
869
+ has_named_vectors = isinstance(collection_info.config.params.vectors, dict)
870
+
871
+ if has_named_vectors and DENSE_VECTORS_NAME not in collection_info.config.params.vectors:
872
+ msg = (
873
+ f"Collection '{collection_name}' already exists in Qdrant, "
874
+ f"but it has been originally created outside of Haystack and is not supported. "
875
+ f"If possible, you should create a new Document Store with Haystack. "
876
+ f"In case you want to migrate the existing collection, see an example script in "
877
+ f"https://github.com/deepset-ai/haystack-core-integrations/blob/main/integrations/qdrant/src/"
878
+ f"haystack_integrations/document_stores/qdrant/migrate_to_sparse.py."
879
+ )
880
+ raise QdrantStoreError(msg)
873
881
 
874
882
  if self.use_sparse_embeddings and not has_named_vectors:
875
883
  msg = (
@@ -882,7 +890,7 @@ class QdrantDocumentStore:
882
890
  )
883
891
  raise QdrantStoreError(msg)
884
892
 
885
- elif not self.use_sparse_embeddings and has_named_vectors:
893
+ if not self.use_sparse_embeddings and has_named_vectors:
886
894
  msg = (
887
895
  f"Collection '{collection_name}' already exists in Qdrant, "
888
896
  f"but it has been originally created with sparse embedding vectors."
@@ -1,5 +1,5 @@
1
1
  from typing import List
2
- from unittest.mock import patch
2
+ from unittest.mock import MagicMock, patch
3
3
 
4
4
  import pytest
5
5
  from haystack import Document
@@ -15,6 +15,7 @@ from haystack.testing.document_store import (
15
15
  from qdrant_client.http import models as rest
16
16
 
17
17
  from haystack_integrations.document_stores.qdrant.document_store import (
18
+ DENSE_VECTORS_NAME,
18
19
  SPARSE_VECTORS_NAME,
19
20
  QdrantDocumentStore,
20
21
  QdrantStoreError,
@@ -151,3 +152,79 @@ class TestQdrantDocumentStore(CountDocumentsTest, WriteDocumentsTest, DeleteDocu
151
152
 
152
153
  with pytest.raises(QdrantStoreError):
153
154
  document_store._query_hybrid(query_sparse_embedding=sparse_embedding, query_embedding=embedding)
155
+
156
+ def test_set_up_collection_with_existing_incompatible_collection(self):
157
+ document_store = QdrantDocumentStore(location=":memory:", use_sparse_embeddings=True)
158
+
159
+ # Mock collection info with named vectors but missing DENSE_VECTORS_NAME
160
+ mock_collection_info = MagicMock()
161
+ mock_collection_info.config.params.vectors = {"some_other_vector": MagicMock()}
162
+
163
+ with patch.object(document_store.client, "collection_exists", return_value=True), patch.object(
164
+ document_store.client, "get_collection", return_value=mock_collection_info
165
+ ):
166
+
167
+ with pytest.raises(QdrantStoreError, match="created outside of Haystack"):
168
+ document_store._set_up_collection("test_collection", 768, False, "cosine", True, False)
169
+
170
+ def test_set_up_collection_use_sparse_embeddings_true_without_named_vectors(self):
171
+ """Test that an error is raised when use_sparse_embeddings is True but collection doesn't have named vectors"""
172
+ document_store = QdrantDocumentStore(location=":memory:", use_sparse_embeddings=True)
173
+
174
+ # Mock collection info without named vectors
175
+ mock_collection_info = MagicMock()
176
+ mock_collection_info.config.params.vectors = MagicMock(spec=rest.VectorsConfig)
177
+
178
+ with patch.object(document_store.client, "collection_exists", return_value=True), patch.object(
179
+ document_store.client, "get_collection", return_value=mock_collection_info
180
+ ):
181
+
182
+ with pytest.raises(QdrantStoreError, match="without sparse embedding vectors"):
183
+ document_store._set_up_collection("test_collection", 768, False, "cosine", True, False)
184
+
185
+ def test_set_up_collection_use_sparse_embeddings_false_with_named_vectors(self):
186
+ """Test that an error is raised when use_sparse_embeddings is False but collection has named vectors"""
187
+ document_store = QdrantDocumentStore(location=":memory:", use_sparse_embeddings=False)
188
+
189
+ # Mock collection info with named vectors
190
+ mock_collection_info = MagicMock()
191
+ mock_collection_info.config.params.vectors = {DENSE_VECTORS_NAME: MagicMock()}
192
+
193
+ with patch.object(document_store.client, "collection_exists", return_value=True), patch.object(
194
+ document_store.client, "get_collection", return_value=mock_collection_info
195
+ ):
196
+
197
+ with pytest.raises(QdrantStoreError, match="with sparse embedding vectors"):
198
+ document_store._set_up_collection("test_collection", 768, False, "cosine", False, False)
199
+
200
+ def test_set_up_collection_with_distance_mismatch(self):
201
+ document_store = QdrantDocumentStore(location=":memory:", use_sparse_embeddings=False, similarity="cosine")
202
+
203
+ # Mock collection info with different distance
204
+ mock_collection_info = MagicMock()
205
+ mock_collection_info.config.params.vectors = MagicMock()
206
+ mock_collection_info.config.params.vectors.distance = rest.Distance.DOT
207
+ mock_collection_info.config.params.vectors.size = 768
208
+
209
+ with patch.object(document_store.client, "collection_exists", return_value=True), patch.object(
210
+ document_store.client, "get_collection", return_value=mock_collection_info
211
+ ):
212
+
213
+ with pytest.raises(ValueError, match="different similarity"):
214
+ document_store._set_up_collection("test_collection", 768, False, "cosine", False, False)
215
+
216
+ def test_set_up_collection_with_dimension_mismatch(self):
217
+ document_store = QdrantDocumentStore(location=":memory:", use_sparse_embeddings=False, similarity="cosine")
218
+
219
+ # Mock collection info with different vector size
220
+ mock_collection_info = MagicMock()
221
+ mock_collection_info.config.params.vectors = MagicMock()
222
+ mock_collection_info.config.params.vectors.distance = rest.Distance.COSINE
223
+ mock_collection_info.config.params.vectors.size = 512
224
+
225
+ with patch.object(document_store.client, "collection_exists", return_value=True), patch.object(
226
+ document_store.client, "get_collection", return_value=mock_collection_info
227
+ ):
228
+
229
+ with pytest.raises(ValueError, match="different vector size"):
230
+ document_store._set_up_collection("test_collection", 768, False, "cosine", False, False)