qdrant-haystack 9.2.0__tar.gz → 9.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. {qdrant_haystack-9.2.0 → qdrant_haystack-9.5.0}/CHANGELOG.md +41 -1
  2. {qdrant_haystack-9.2.0 → qdrant_haystack-9.5.0}/PKG-INFO +6 -21
  3. qdrant_haystack-9.5.0/README.md +13 -0
  4. qdrant_haystack-9.5.0/pydoc/config_docusaurus.yml +30 -0
  5. {qdrant_haystack-9.2.0 → qdrant_haystack-9.5.0}/pyproject.toml +3 -7
  6. {qdrant_haystack-9.2.0 → qdrant_haystack-9.5.0}/src/haystack_integrations/components/retrievers/qdrant/retriever.py +32 -32
  7. {qdrant_haystack-9.2.0 → qdrant_haystack-9.5.0}/src/haystack_integrations/document_stores/qdrant/converters.py +3 -3
  8. {qdrant_haystack-9.2.0 → qdrant_haystack-9.5.0}/src/haystack_integrations/document_stores/qdrant/document_store.py +418 -83
  9. {qdrant_haystack-9.2.0 → qdrant_haystack-9.5.0}/src/haystack_integrations/document_stores/qdrant/filters.py +10 -10
  10. {qdrant_haystack-9.2.0 → qdrant_haystack-9.5.0}/tests/test_dict_converters.py +0 -3
  11. {qdrant_haystack-9.2.0 → qdrant_haystack-9.5.0}/tests/test_document_store.py +245 -15
  12. qdrant_haystack-9.5.0/tests/test_document_store_async.py +476 -0
  13. {qdrant_haystack-9.2.0 → qdrant_haystack-9.5.0}/tests/test_embedding_retriever.py +11 -14
  14. {qdrant_haystack-9.2.0 → qdrant_haystack-9.5.0}/tests/test_filters.py +1 -3
  15. {qdrant_haystack-9.2.0 → qdrant_haystack-9.5.0}/tests/test_hybrid_retriever.py +0 -1
  16. {qdrant_haystack-9.2.0 → qdrant_haystack-9.5.0}/tests/test_sparse_embedding_retriever.py +5 -8
  17. qdrant_haystack-9.2.0/README.md +0 -28
  18. qdrant_haystack-9.2.0/pydoc/config.yml +0 -32
  19. qdrant_haystack-9.2.0/tests/test_document_store_async.py +0 -220
  20. {qdrant_haystack-9.2.0 → qdrant_haystack-9.5.0}/.gitignore +0 -0
  21. {qdrant_haystack-9.2.0 → qdrant_haystack-9.5.0}/LICENSE.txt +0 -0
  22. {qdrant_haystack-9.2.0 → qdrant_haystack-9.5.0}/examples/embedding_retrieval.py +0 -0
  23. {qdrant_haystack-9.2.0 → qdrant_haystack-9.5.0}/src/haystack_integrations/components/retrievers/py.typed +0 -0
  24. {qdrant_haystack-9.2.0 → qdrant_haystack-9.5.0}/src/haystack_integrations/components/retrievers/qdrant/__init__.py +0 -0
  25. {qdrant_haystack-9.2.0 → qdrant_haystack-9.5.0}/src/haystack_integrations/document_stores/py.typed +0 -0
  26. {qdrant_haystack-9.2.0 → qdrant_haystack-9.5.0}/src/haystack_integrations/document_stores/qdrant/__init__.py +0 -0
  27. {qdrant_haystack-9.2.0 → qdrant_haystack-9.5.0}/src/haystack_integrations/document_stores/qdrant/migrate_to_sparse.py +0 -0
  28. {qdrant_haystack-9.2.0 → qdrant_haystack-9.5.0}/tests/__init__.py +0 -0
  29. {qdrant_haystack-9.2.0 → qdrant_haystack-9.5.0}/tests/conftest.py +0 -0
  30. {qdrant_haystack-9.2.0 → qdrant_haystack-9.5.0}/tests/test_converters.py +0 -0
@@ -1,6 +1,46 @@
1
1
  # Changelog
2
2
 
3
- ## [integrations/qdrant-v9.1.3] - 2025-05-28
3
+ ## [integrations/qdrant-v9.4.0] - 2025-11-18
4
+
5
+ ### 🧹 Chores
6
+
7
+ - [**breaking**] Qdrant - remove `init_from` init parameter for compatibility with `qdrant-client==1.16.0` (#2531)
8
+
9
+ ### 🌀 Miscellaneous
10
+
11
+ - Enhancement: Adopt PEP 585 type hinting (part 5) (#2528)
12
+
13
+ ## [integrations/qdrant-v9.3.0] - 2025-11-11
14
+
15
+ ### 🚀 Features
16
+
17
+ - Adding `delete_all_docs` to Qdrant document store (#2363)
18
+
19
+ ### 📚 Documentation
20
+
21
+ - Add pydoc configurations for Docusaurus (#2411)
22
+
23
+ ### ⚙️ CI
24
+
25
+ - Change pytest command (#2475)
26
+
27
+ ### 🧹 Chores
28
+
29
+ - Remove black (#1985)
30
+ - Standardize readmes - part 2 (#2205)
31
+
32
+
33
+ ## [integrations/qdrant-v9.2.0] - 2025-06-12
34
+
35
+ ### 🐛 Bug Fixes
36
+
37
+ - Fix Qdrant types + add py.typed (#1919)
38
+
39
+
40
+ ### 🧹 Chores
41
+
42
+ - Align core-integrations Hatch scripts (#1898)
43
+ - Update md files for new hatch scripts (#1911)
4
44
 
5
45
  ### 🌀 Miscellaneous
6
46
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: qdrant-haystack
3
- Version: 9.2.0
3
+ Version: 9.5.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
@@ -28,26 +28,11 @@ Description-Content-Type: text/markdown
28
28
  [![PyPI - Version](https://img.shields.io/pypi/v/qdrant-haystack.svg)](https://pypi.org/project/qdrant-haystack)
29
29
  [![PyPI - Python Version](https://img.shields.io/pypi/pyversions/qdrant-haystack.svg)](https://pypi.org/project/qdrant-haystack)
30
30
 
31
- -----
31
+ - [Integration page](https://haystack.deepset.ai/integrations/qdrant-document-store)
32
+ - [Changelog](https://github.com/deepset-ai/haystack-core-integrations/blob/main/integrations/qdrant/CHANGELOG.md)
32
33
 
33
- **Table of Contents**
34
+ ---
34
35
 
35
- - [Installation](#installation)
36
- - [License](#license)
36
+ ## Contributing
37
37
 
38
- ## Installation
39
-
40
- ```console
41
- pip install qdrant-haystack
42
- ```
43
-
44
- ## Testing
45
- The test suites use Qdrant's in-memory instance. No additional steps required.
46
-
47
- ```console
48
- hatch run test:all
49
- ```
50
-
51
- ## License
52
-
53
- `qdrant-haystack` is distributed under the terms of the [Apache-2.0](https://spdx.org/licenses/Apache-2.0.html) license.
38
+ Refer to the general [Contribution Guidelines](https://github.com/deepset-ai/haystack-core-integrations/blob/main/CONTRIBUTING.md).
@@ -0,0 +1,13 @@
1
+ # qdrant-haystack
2
+
3
+ [![PyPI - Version](https://img.shields.io/pypi/v/qdrant-haystack.svg)](https://pypi.org/project/qdrant-haystack)
4
+ [![PyPI - Python Version](https://img.shields.io/pypi/pyversions/qdrant-haystack.svg)](https://pypi.org/project/qdrant-haystack)
5
+
6
+ - [Integration page](https://haystack.deepset.ai/integrations/qdrant-document-store)
7
+ - [Changelog](https://github.com/deepset-ai/haystack-core-integrations/blob/main/integrations/qdrant/CHANGELOG.md)
8
+
9
+ ---
10
+
11
+ ## Contributing
12
+
13
+ Refer to the general [Contribution Guidelines](https://github.com/deepset-ai/haystack-core-integrations/blob/main/CONTRIBUTING.md).
@@ -0,0 +1,30 @@
1
+ loaders:
2
+ - ignore_when_discovered:
3
+ - __init__
4
+ modules:
5
+ - haystack_integrations.components.retrievers.qdrant.retriever
6
+ - haystack_integrations.document_stores.qdrant.document_store
7
+ - haystack_integrations.document_stores.qdrant.migrate_to_sparse
8
+ search_path:
9
+ - ../src
10
+ type: haystack_pydoc_tools.loaders.CustomPythonLoader
11
+ processors:
12
+ - do_not_filter_modules: false
13
+ documented_only: true
14
+ expression: null
15
+ skip_empty_modules: true
16
+ type: filter
17
+ - type: smart
18
+ - type: crossref
19
+ renderer:
20
+ description: Qdrant integration for Haystack
21
+ id: integrations-qdrant
22
+ markdown:
23
+ add_member_class_prefix: false
24
+ add_method_class_prefix: true
25
+ classdef_code_block: false
26
+ descriptive_class_title: false
27
+ descriptive_module_title: true
28
+ filename: qdrant.md
29
+ title: Qdrant
30
+ type: haystack_pydoc_tools.renderers.DocusaurusRenderer
@@ -49,7 +49,7 @@ installer = "uv"
49
49
  dependencies = ["haystack-pydoc-tools", "ruff"]
50
50
 
51
51
  [tool.hatch.envs.default.scripts]
52
- docs = ["pydoc-markdown pydoc/config.yml"]
52
+ docs = ["pydoc-markdown pydoc/config_docusaurus.yml"]
53
53
  fmt = "ruff check --fix {args} && ruff format {args}"
54
54
  fmt-check = "ruff check {args} && ruff format --check {args}"
55
55
 
@@ -67,7 +67,7 @@ dependencies = [
67
67
  unit = 'pytest -m "not integration" {args:tests}'
68
68
  integration = 'pytest -m "integration" {args:tests}'
69
69
  all = 'pytest {args:tests}'
70
- cov-retry = 'all --cov=haystack_integrations --reruns 3 --reruns-delay 30 -x'
70
+ cov-retry = 'pytest --cov=haystack_integrations --reruns 3 --reruns-delay 30 -x {args:tests}'
71
71
 
72
72
  types = """mypy -p haystack_integrations.document_stores.qdrant \
73
73
  -p haystack_integrations.components.retrievers.qdrant {args}"""
@@ -78,13 +78,9 @@ non_interactive = true
78
78
  check_untyped_defs = true
79
79
  disallow_incomplete_defs = true
80
80
 
81
- [tool.black]
82
- target-version = ["py38"]
83
- line-length = 120
84
- skip-string-normalization = true
85
81
 
86
82
  [tool.ruff]
87
- target-version = "py38"
83
+ target-version = "py39"
88
84
  line-length = 120
89
85
 
90
86
  [tool.ruff.lint]
@@ -1,4 +1,4 @@
1
- from typing import Any, Dict, List, Optional, Union
1
+ from typing import Any, Optional, Union
2
2
 
3
3
  from haystack import Document, component, default_from_dict, default_to_dict
4
4
  from haystack.dataclasses.sparse_embedding import SparseEmbedding
@@ -43,7 +43,7 @@ class QdrantEmbeddingRetriever:
43
43
  def __init__(
44
44
  self,
45
45
  document_store: QdrantDocumentStore,
46
- filters: Optional[Union[Dict[str, Any], models.Filter]] = None,
46
+ filters: Optional[Union[dict[str, Any], models.Filter]] = None,
47
47
  top_k: int = 10,
48
48
  scale_score: bool = False,
49
49
  return_embedding: bool = False,
@@ -89,7 +89,7 @@ class QdrantEmbeddingRetriever:
89
89
  self._group_by = group_by
90
90
  self._group_size = group_size
91
91
 
92
- def to_dict(self) -> Dict[str, Any]:
92
+ def to_dict(self) -> dict[str, Any]:
93
93
  """
94
94
  Serializes the component to a dictionary.
95
95
 
@@ -113,7 +113,7 @@ class QdrantEmbeddingRetriever:
113
113
  return d
114
114
 
115
115
  @classmethod
116
- def from_dict(cls, data: Dict[str, Any]) -> "QdrantEmbeddingRetriever":
116
+ def from_dict(cls, data: dict[str, Any]) -> "QdrantEmbeddingRetriever":
117
117
  """
118
118
  Deserializes the component from a dictionary.
119
119
 
@@ -130,18 +130,18 @@ class QdrantEmbeddingRetriever:
130
130
  data["init_parameters"]["filter_policy"] = FilterPolicy.from_str(filter_policy)
131
131
  return default_from_dict(cls, data)
132
132
 
133
- @component.output_types(documents=List[Document])
133
+ @component.output_types(documents=list[Document])
134
134
  def run(
135
135
  self,
136
- query_embedding: List[float],
137
- filters: Optional[Union[Dict[str, Any], models.Filter]] = None,
136
+ query_embedding: list[float],
137
+ filters: Optional[Union[dict[str, Any], models.Filter]] = None,
138
138
  top_k: Optional[int] = None,
139
139
  scale_score: Optional[bool] = None,
140
140
  return_embedding: Optional[bool] = None,
141
141
  score_threshold: Optional[float] = None,
142
142
  group_by: Optional[str] = None,
143
143
  group_size: Optional[int] = None,
144
- ) -> Dict[str, List[Document]]:
144
+ ) -> dict[str, list[Document]]:
145
145
  """
146
146
  Run the Embedding Retriever on the given input data.
147
147
 
@@ -185,18 +185,18 @@ class QdrantEmbeddingRetriever:
185
185
 
186
186
  return {"documents": docs}
187
187
 
188
- @component.output_types(documents=List[Document])
188
+ @component.output_types(documents=list[Document])
189
189
  async def run_async(
190
190
  self,
191
- query_embedding: List[float],
192
- filters: Optional[Union[Dict[str, Any], models.Filter]] = None,
191
+ query_embedding: list[float],
192
+ filters: Optional[Union[dict[str, Any], models.Filter]] = None,
193
193
  top_k: Optional[int] = None,
194
194
  scale_score: Optional[bool] = None,
195
195
  return_embedding: Optional[bool] = None,
196
196
  score_threshold: Optional[float] = None,
197
197
  group_by: Optional[str] = None,
198
198
  group_size: Optional[int] = None,
199
- ) -> Dict[str, List[Document]]:
199
+ ) -> dict[str, list[Document]]:
200
200
  """
201
201
  Asynchronously run the Embedding Retriever on the given input data.
202
202
 
@@ -271,7 +271,7 @@ class QdrantSparseEmbeddingRetriever:
271
271
  def __init__(
272
272
  self,
273
273
  document_store: QdrantDocumentStore,
274
- filters: Optional[Union[Dict[str, Any], models.Filter]] = None,
274
+ filters: Optional[Union[dict[str, Any], models.Filter]] = None,
275
275
  top_k: int = 10,
276
276
  scale_score: bool = False,
277
277
  return_embedding: bool = False,
@@ -317,7 +317,7 @@ class QdrantSparseEmbeddingRetriever:
317
317
  self._group_by = group_by
318
318
  self._group_size = group_size
319
319
 
320
- def to_dict(self) -> Dict[str, Any]:
320
+ def to_dict(self) -> dict[str, Any]:
321
321
  """
322
322
  Serializes the component to a dictionary.
323
323
 
@@ -341,7 +341,7 @@ class QdrantSparseEmbeddingRetriever:
341
341
  return d
342
342
 
343
343
  @classmethod
344
- def from_dict(cls, data: Dict[str, Any]) -> "QdrantSparseEmbeddingRetriever":
344
+ def from_dict(cls, data: dict[str, Any]) -> "QdrantSparseEmbeddingRetriever":
345
345
  """
346
346
  Deserializes the component from a dictionary.
347
347
 
@@ -358,18 +358,18 @@ class QdrantSparseEmbeddingRetriever:
358
358
  data["init_parameters"]["filter_policy"] = FilterPolicy.from_str(filter_policy)
359
359
  return default_from_dict(cls, data)
360
360
 
361
- @component.output_types(documents=List[Document])
361
+ @component.output_types(documents=list[Document])
362
362
  def run(
363
363
  self,
364
364
  query_sparse_embedding: SparseEmbedding,
365
- filters: Optional[Union[Dict[str, Any], models.Filter]] = None,
365
+ filters: Optional[Union[dict[str, Any], models.Filter]] = None,
366
366
  top_k: Optional[int] = None,
367
367
  scale_score: Optional[bool] = None,
368
368
  return_embedding: Optional[bool] = None,
369
369
  score_threshold: Optional[float] = None,
370
370
  group_by: Optional[str] = None,
371
371
  group_size: Optional[int] = None,
372
- ) -> Dict[str, List[Document]]:
372
+ ) -> dict[str, list[Document]]:
373
373
  """
374
374
  Run the Sparse Embedding Retriever on the given input data.
375
375
 
@@ -418,18 +418,18 @@ class QdrantSparseEmbeddingRetriever:
418
418
 
419
419
  return {"documents": docs}
420
420
 
421
- @component.output_types(documents=List[Document])
421
+ @component.output_types(documents=list[Document])
422
422
  async def run_async(
423
423
  self,
424
424
  query_sparse_embedding: SparseEmbedding,
425
- filters: Optional[Union[Dict[str, Any], models.Filter]] = None,
425
+ filters: Optional[Union[dict[str, Any], models.Filter]] = None,
426
426
  top_k: Optional[int] = None,
427
427
  scale_score: Optional[bool] = None,
428
428
  return_embedding: Optional[bool] = None,
429
429
  score_threshold: Optional[float] = None,
430
430
  group_by: Optional[str] = None,
431
431
  group_size: Optional[int] = None,
432
- ) -> Dict[str, List[Document]]:
432
+ ) -> dict[str, list[Document]]:
433
433
  """
434
434
  Asynchronously run the Sparse Embedding Retriever on the given input data.
435
435
 
@@ -515,7 +515,7 @@ class QdrantHybridRetriever:
515
515
  def __init__(
516
516
  self,
517
517
  document_store: QdrantDocumentStore,
518
- filters: Optional[Union[Dict[str, Any], models.Filter]] = None,
518
+ filters: Optional[Union[dict[str, Any], models.Filter]] = None,
519
519
  top_k: int = 10,
520
520
  return_embedding: bool = False,
521
521
  filter_policy: Union[str, FilterPolicy] = FilterPolicy.REPLACE,
@@ -558,7 +558,7 @@ class QdrantHybridRetriever:
558
558
  self._group_by = group_by
559
559
  self._group_size = group_size
560
560
 
561
- def to_dict(self) -> Dict[str, Any]:
561
+ def to_dict(self) -> dict[str, Any]:
562
562
  """
563
563
  Serializes the component to a dictionary.
564
564
 
@@ -578,7 +578,7 @@ class QdrantHybridRetriever:
578
578
  )
579
579
 
580
580
  @classmethod
581
- def from_dict(cls, data: Dict[str, Any]) -> "QdrantHybridRetriever":
581
+ def from_dict(cls, data: dict[str, Any]) -> "QdrantHybridRetriever":
582
582
  """
583
583
  Deserializes the component from a dictionary.
584
584
 
@@ -595,18 +595,18 @@ class QdrantHybridRetriever:
595
595
  data["init_parameters"]["filter_policy"] = FilterPolicy.from_str(filter_policy)
596
596
  return default_from_dict(cls, data)
597
597
 
598
- @component.output_types(documents=List[Document])
598
+ @component.output_types(documents=list[Document])
599
599
  def run(
600
600
  self,
601
- query_embedding: List[float],
601
+ query_embedding: list[float],
602
602
  query_sparse_embedding: SparseEmbedding,
603
- filters: Optional[Union[Dict[str, Any], models.Filter]] = None,
603
+ filters: Optional[Union[dict[str, Any], models.Filter]] = None,
604
604
  top_k: Optional[int] = None,
605
605
  return_embedding: Optional[bool] = None,
606
606
  score_threshold: Optional[float] = None,
607
607
  group_by: Optional[str] = None,
608
608
  group_size: Optional[int] = None,
609
- ) -> Dict[str, List[Document]]:
609
+ ) -> dict[str, list[Document]]:
610
610
  """
611
611
  Run the Sparse Embedding Retriever on the given input data.
612
612
 
@@ -655,18 +655,18 @@ class QdrantHybridRetriever:
655
655
 
656
656
  return {"documents": docs}
657
657
 
658
- @component.output_types(documents=List[Document])
658
+ @component.output_types(documents=list[Document])
659
659
  async def run_async(
660
660
  self,
661
- query_embedding: List[float],
661
+ query_embedding: list[float],
662
662
  query_sparse_embedding: SparseEmbedding,
663
- filters: Optional[Union[Dict[str, Any], models.Filter]] = None,
663
+ filters: Optional[Union[dict[str, Any], models.Filter]] = None,
664
664
  top_k: Optional[int] = None,
665
665
  return_embedding: Optional[bool] = None,
666
666
  score_threshold: Optional[float] = None,
667
667
  group_by: Optional[str] = None,
668
668
  group_size: Optional[int] = None,
669
- ) -> Dict[str, List[Document]]:
669
+ ) -> dict[str, list[Document]]:
670
670
  """
671
671
  Asynchronously run the Sparse Embedding Retriever on the given input data.
672
672
 
@@ -1,5 +1,5 @@
1
1
  import uuid
2
- from typing import List, Union
2
+ from typing import Union
3
3
 
4
4
  from haystack import logging
5
5
  from haystack.dataclasses import Document
@@ -15,10 +15,10 @@ UUID_NAMESPACE = uuid.UUID("3896d314-1e95-4a3a-b45a-945f9f0b541d")
15
15
 
16
16
 
17
17
  def convert_haystack_documents_to_qdrant_points(
18
- documents: List[Document],
18
+ documents: list[Document],
19
19
  *,
20
20
  use_sparse_embeddings: bool,
21
- ) -> List[rest.PointStruct]:
21
+ ) -> list[rest.PointStruct]:
22
22
  points = []
23
23
  for document in documents:
24
24
  payload = document.to_dict(flatten=False)