qdrant-haystack 9.2.0__tar.gz → 10.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 (30) hide show
  1. {qdrant_haystack-9.2.0 → qdrant_haystack-10.0.0}/CHANGELOG.md +56 -1
  2. {qdrant_haystack-9.2.0 → qdrant_haystack-10.0.0}/PKG-INFO +8 -24
  3. qdrant_haystack-10.0.0/README.md +13 -0
  4. qdrant_haystack-10.0.0/pydoc/config_docusaurus.yml +30 -0
  5. {qdrant_haystack-9.2.0 → qdrant_haystack-10.0.0}/pyproject.toml +5 -15
  6. {qdrant_haystack-9.2.0 → qdrant_haystack-10.0.0}/src/haystack_integrations/components/retrievers/qdrant/retriever.py +78 -78
  7. {qdrant_haystack-9.2.0 → qdrant_haystack-10.0.0}/src/haystack_integrations/document_stores/qdrant/converters.py +3 -4
  8. {qdrant_haystack-9.2.0 → qdrant_haystack-10.0.0}/src/haystack_integrations/document_stores/qdrant/document_store.py +463 -128
  9. {qdrant_haystack-9.2.0 → qdrant_haystack-10.0.0}/src/haystack_integrations/document_stores/qdrant/filters.py +16 -15
  10. {qdrant_haystack-9.2.0 → qdrant_haystack-10.0.0}/tests/test_dict_converters.py +0 -3
  11. {qdrant_haystack-9.2.0 → qdrant_haystack-10.0.0}/tests/test_document_store.py +245 -15
  12. qdrant_haystack-10.0.0/tests/test_document_store_async.py +476 -0
  13. {qdrant_haystack-9.2.0 → qdrant_haystack-10.0.0}/tests/test_embedding_retriever.py +11 -14
  14. {qdrant_haystack-9.2.0 → qdrant_haystack-10.0.0}/tests/test_filters.py +1 -3
  15. {qdrant_haystack-9.2.0 → qdrant_haystack-10.0.0}/tests/test_hybrid_retriever.py +0 -1
  16. {qdrant_haystack-9.2.0 → qdrant_haystack-10.0.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-10.0.0}/.gitignore +0 -0
  21. {qdrant_haystack-9.2.0 → qdrant_haystack-10.0.0}/LICENSE.txt +0 -0
  22. {qdrant_haystack-9.2.0 → qdrant_haystack-10.0.0}/examples/embedding_retrieval.py +0 -0
  23. {qdrant_haystack-9.2.0 → qdrant_haystack-10.0.0}/src/haystack_integrations/components/retrievers/py.typed +0 -0
  24. {qdrant_haystack-9.2.0 → qdrant_haystack-10.0.0}/src/haystack_integrations/components/retrievers/qdrant/__init__.py +0 -0
  25. {qdrant_haystack-9.2.0 → qdrant_haystack-10.0.0}/src/haystack_integrations/document_stores/py.typed +0 -0
  26. {qdrant_haystack-9.2.0 → qdrant_haystack-10.0.0}/src/haystack_integrations/document_stores/qdrant/__init__.py +0 -0
  27. {qdrant_haystack-9.2.0 → qdrant_haystack-10.0.0}/src/haystack_integrations/document_stores/qdrant/migrate_to_sparse.py +0 -0
  28. {qdrant_haystack-9.2.0 → qdrant_haystack-10.0.0}/tests/__init__.py +0 -0
  29. {qdrant_haystack-9.2.0 → qdrant_haystack-10.0.0}/tests/conftest.py +0 -0
  30. {qdrant_haystack-9.2.0 → qdrant_haystack-10.0.0}/tests/test_converters.py +0 -0
@@ -1,6 +1,61 @@
1
1
  # Changelog
2
2
 
3
- ## [integrations/qdrant-v9.1.3] - 2025-05-28
3
+ ## [integrations/qdrant-v9.5.0] - 2026-01-07
4
+
5
+ ### 🚀 Features
6
+
7
+ - Adding `delete_by_filter()` and `update_by_filter()` to `QdrantDocumentStore` (#2650)
8
+
9
+ ### 🐛 Bug Fixes
10
+
11
+ - Fix types for qdrant-client 1.16.1 (#2561)
12
+
13
+ ### 🧹 Chores
14
+
15
+ - Remove Readme API CI workflow and configs (#2573)
16
+
17
+
18
+ ## [integrations/qdrant-v9.4.0] - 2025-11-18
19
+
20
+ ### 🧹 Chores
21
+
22
+ - [**breaking**] Qdrant - remove `init_from` init parameter for compatibility with `qdrant-client==1.16.0` (#2531)
23
+
24
+ ### 🌀 Miscellaneous
25
+
26
+ - Enhancement: Adopt PEP 585 type hinting (part 5) (#2528)
27
+
28
+ ## [integrations/qdrant-v9.3.0] - 2025-11-11
29
+
30
+ ### 🚀 Features
31
+
32
+ - Adding `delete_all_docs` to Qdrant document store (#2363)
33
+
34
+ ### 📚 Documentation
35
+
36
+ - Add pydoc configurations for Docusaurus (#2411)
37
+
38
+ ### ⚙️ CI
39
+
40
+ - Change pytest command (#2475)
41
+
42
+ ### 🧹 Chores
43
+
44
+ - Remove black (#1985)
45
+ - Standardize readmes - part 2 (#2205)
46
+
47
+
48
+ ## [integrations/qdrant-v9.2.0] - 2025-06-12
49
+
50
+ ### 🐛 Bug Fixes
51
+
52
+ - Fix Qdrant types + add py.typed (#1919)
53
+
54
+
55
+ ### 🧹 Chores
56
+
57
+ - Align core-integrations Hatch scripts (#1898)
58
+ - Update md files for new hatch scripts (#1911)
4
59
 
5
60
  ### 🌀 Miscellaneous
6
61
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: qdrant-haystack
3
- Version: 9.2.0
3
+ Version: 10.0.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,15 +11,14 @@ 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
22
- Requires-Dist: haystack-ai>=2.11.0
20
+ Requires-Python: >=3.10
21
+ Requires-Dist: haystack-ai>=2.22.0
23
22
  Requires-Dist: qdrant-client>=1.12.0
24
23
  Description-Content-Type: text/markdown
25
24
 
@@ -28,26 +27,11 @@ Description-Content-Type: text/markdown
28
27
  [![PyPI - Version](https://img.shields.io/pypi/v/qdrant-haystack.svg)](https://pypi.org/project/qdrant-haystack)
29
28
  [![PyPI - Python Version](https://img.shields.io/pypi/pyversions/qdrant-haystack.svg)](https://pypi.org/project/qdrant-haystack)
30
29
 
31
- -----
30
+ - [Integration page](https://haystack.deepset.ai/integrations/qdrant-document-store)
31
+ - [Changelog](https://github.com/deepset-ai/haystack-core-integrations/blob/main/integrations/qdrant/CHANGELOG.md)
32
32
 
33
- **Table of Contents**
33
+ ---
34
34
 
35
- - [Installation](#installation)
36
- - [License](#license)
35
+ ## Contributing
37
36
 
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.
37
+ 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
@@ -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.9"
10
+ requires-python = ">=3.10"
11
11
  license = "Apache-2.0"
12
12
  keywords = []
13
13
  authors = [
@@ -18,7 +18,6 @@ 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.9",
22
21
  "Programming Language :: Python :: 3.10",
23
22
  "Programming Language :: Python :: 3.11",
24
23
  "Programming Language :: Python :: 3.12",
@@ -26,7 +25,7 @@ classifiers = [
26
25
  "Programming Language :: Python :: Implementation :: CPython",
27
26
  "Programming Language :: Python :: Implementation :: PyPy",
28
27
  ]
29
- dependencies = ["haystack-ai>=2.11.0", "qdrant-client>=1.12.0"]
28
+ dependencies = ["haystack-ai>=2.22.0", "qdrant-client>=1.12.0"]
30
29
 
31
30
  [project.urls]
32
31
  Source = "https://github.com/deepset-ai/haystack-core-integrations"
@@ -49,8 +48,8 @@ installer = "uv"
49
48
  dependencies = ["haystack-pydoc-tools", "ruff"]
50
49
 
51
50
  [tool.hatch.envs.default.scripts]
52
- docs = ["pydoc-markdown pydoc/config.yml"]
53
- fmt = "ruff check --fix {args} && ruff format {args}"
51
+ docs = ["pydoc-markdown pydoc/config_docusaurus.yml"]
52
+ fmt = "ruff check --fix {args}; ruff format {args}"
54
53
  fmt-check = "ruff check {args} && ruff format --check {args}"
55
54
 
56
55
  [tool.hatch.envs.test]
@@ -67,7 +66,7 @@ dependencies = [
67
66
  unit = 'pytest -m "not integration" {args:tests}'
68
67
  integration = 'pytest -m "integration" {args:tests}'
69
68
  all = 'pytest {args:tests}'
70
- cov-retry = 'all --cov=haystack_integrations --reruns 3 --reruns-delay 30 -x'
69
+ cov-retry = 'pytest --cov=haystack_integrations --reruns 3 --reruns-delay 30 -x {args:tests}'
71
70
 
72
71
  types = """mypy -p haystack_integrations.document_stores.qdrant \
73
72
  -p haystack_integrations.components.retrievers.qdrant {args}"""
@@ -78,13 +77,8 @@ non_interactive = true
78
77
  check_untyped_defs = true
79
78
  disallow_incomplete_defs = true
80
79
 
81
- [tool.black]
82
- target-version = ["py38"]
83
- line-length = 120
84
- skip-string-normalization = true
85
80
 
86
81
  [tool.ruff]
87
- target-version = "py38"
88
82
  line-length = 120
89
83
 
90
84
  [tool.ruff.lint]
@@ -136,10 +130,6 @@ ignore = [
136
130
  # Ignore assertions
137
131
  "S101",
138
132
  ]
139
- unfixable = [
140
- # Don't touch unused imports
141
- "F401",
142
- ]
143
133
 
144
134
  [tool.ruff.lint.flake8-tidy-imports]
145
135
  ban-relative-imports = "parents"
@@ -1,4 +1,4 @@
1
- from typing import Any, Dict, List, Optional, Union
1
+ from typing import Any
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,14 +43,14 @@ 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: dict[str, Any] | models.Filter | None = None,
47
47
  top_k: int = 10,
48
48
  scale_score: bool = False,
49
49
  return_embedding: bool = False,
50
- filter_policy: Union[str, FilterPolicy] = FilterPolicy.REPLACE,
51
- score_threshold: Optional[float] = None,
52
- group_by: Optional[str] = None,
53
- group_size: Optional[int] = None,
50
+ filter_policy: str | FilterPolicy = FilterPolicy.REPLACE,
51
+ score_threshold: float | None = None,
52
+ group_by: str | None = None,
53
+ group_size: int | None = None,
54
54
  ) -> None:
55
55
  """
56
56
  Create a QdrantEmbeddingRetriever component.
@@ -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,
138
- top_k: Optional[int] = None,
139
- scale_score: Optional[bool] = None,
140
- return_embedding: Optional[bool] = None,
141
- score_threshold: Optional[float] = None,
142
- group_by: Optional[str] = None,
143
- group_size: Optional[int] = None,
144
- ) -> Dict[str, List[Document]]:
136
+ query_embedding: list[float],
137
+ filters: dict[str, Any] | models.Filter | None = None,
138
+ top_k: int | None = None,
139
+ scale_score: bool | None = None,
140
+ return_embedding: bool | None = None,
141
+ score_threshold: float | None = None,
142
+ group_by: str | None = None,
143
+ group_size: int | None = None,
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,
193
- top_k: Optional[int] = None,
194
- scale_score: Optional[bool] = None,
195
- return_embedding: Optional[bool] = None,
196
- score_threshold: Optional[float] = None,
197
- group_by: Optional[str] = None,
198
- group_size: Optional[int] = None,
199
- ) -> Dict[str, List[Document]]:
191
+ query_embedding: list[float],
192
+ filters: dict[str, Any] | models.Filter | None = None,
193
+ top_k: int | None = None,
194
+ scale_score: bool | None = None,
195
+ return_embedding: bool | None = None,
196
+ score_threshold: float | None = None,
197
+ group_by: str | None = None,
198
+ group_size: int | None = None,
199
+ ) -> dict[str, list[Document]]:
200
200
  """
201
201
  Asynchronously run the Embedding Retriever on the given input data.
202
202
 
@@ -271,14 +271,14 @@ 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: dict[str, Any] | models.Filter | None = None,
275
275
  top_k: int = 10,
276
276
  scale_score: bool = False,
277
277
  return_embedding: bool = False,
278
- filter_policy: Union[str, FilterPolicy] = FilterPolicy.REPLACE,
279
- score_threshold: Optional[float] = None,
280
- group_by: Optional[str] = None,
281
- group_size: Optional[int] = None,
278
+ filter_policy: str | FilterPolicy = FilterPolicy.REPLACE,
279
+ score_threshold: float | None = None,
280
+ group_by: str | None = None,
281
+ group_size: int | None = None,
282
282
  ) -> None:
283
283
  """
284
284
  Create a QdrantSparseEmbeddingRetriever component.
@@ -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,
366
- top_k: Optional[int] = None,
367
- scale_score: Optional[bool] = None,
368
- return_embedding: Optional[bool] = None,
369
- score_threshold: Optional[float] = None,
370
- group_by: Optional[str] = None,
371
- group_size: Optional[int] = None,
372
- ) -> Dict[str, List[Document]]:
365
+ filters: dict[str, Any] | models.Filter | None = None,
366
+ top_k: int | None = None,
367
+ scale_score: bool | None = None,
368
+ return_embedding: bool | None = None,
369
+ score_threshold: float | None = None,
370
+ group_by: str | None = None,
371
+ group_size: int | None = None,
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,
426
- top_k: Optional[int] = None,
427
- scale_score: Optional[bool] = None,
428
- return_embedding: Optional[bool] = None,
429
- score_threshold: Optional[float] = None,
430
- group_by: Optional[str] = None,
431
- group_size: Optional[int] = None,
432
- ) -> Dict[str, List[Document]]:
425
+ filters: dict[str, Any] | models.Filter | None = None,
426
+ top_k: int | None = None,
427
+ scale_score: bool | None = None,
428
+ return_embedding: bool | None = None,
429
+ score_threshold: float | None = None,
430
+ group_by: str | None = None,
431
+ group_size: int | None = None,
432
+ ) -> dict[str, list[Document]]:
433
433
  """
434
434
  Asynchronously run the Sparse Embedding Retriever on the given input data.
435
435
 
@@ -515,13 +515,13 @@ 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: dict[str, Any] | models.Filter | None = None,
519
519
  top_k: int = 10,
520
520
  return_embedding: bool = False,
521
- filter_policy: Union[str, FilterPolicy] = FilterPolicy.REPLACE,
522
- score_threshold: Optional[float] = None,
523
- group_by: Optional[str] = None,
524
- group_size: Optional[int] = None,
521
+ filter_policy: str | FilterPolicy = FilterPolicy.REPLACE,
522
+ score_threshold: float | None = None,
523
+ group_by: str | None = None,
524
+ group_size: int | None = None,
525
525
  ) -> None:
526
526
  """
527
527
  Create a QdrantHybridRetriever component.
@@ -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,
604
- top_k: Optional[int] = None,
605
- return_embedding: Optional[bool] = None,
606
- score_threshold: Optional[float] = None,
607
- group_by: Optional[str] = None,
608
- group_size: Optional[int] = None,
609
- ) -> Dict[str, List[Document]]:
603
+ filters: dict[str, Any] | models.Filter | None = None,
604
+ top_k: int | None = None,
605
+ return_embedding: bool | None = None,
606
+ score_threshold: float | None = None,
607
+ group_by: str | None = None,
608
+ group_size: int | None = None,
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,
664
- top_k: Optional[int] = None,
665
- return_embedding: Optional[bool] = None,
666
- score_threshold: Optional[float] = None,
667
- group_by: Optional[str] = None,
668
- group_size: Optional[int] = None,
669
- ) -> Dict[str, List[Document]]:
663
+ filters: dict[str, Any] | models.Filter | None = None,
664
+ top_k: int | None = None,
665
+ return_embedding: bool | None = None,
666
+ score_threshold: float | None = None,
667
+ group_by: str | None = None,
668
+ group_size: int | None = None,
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,4 @@
1
1
  import uuid
2
- from typing import List, Union
3
2
 
4
3
  from haystack import logging
5
4
  from haystack.dataclasses import Document
@@ -15,10 +14,10 @@ UUID_NAMESPACE = uuid.UUID("3896d314-1e95-4a3a-b45a-945f9f0b541d")
15
14
 
16
15
 
17
16
  def convert_haystack_documents_to_qdrant_points(
18
- documents: List[Document],
17
+ documents: list[Document],
19
18
  *,
20
19
  use_sparse_embeddings: bool,
21
- ) -> List[rest.PointStruct]:
20
+ ) -> list[rest.PointStruct]:
22
21
  points = []
23
22
  for document in documents:
24
23
  payload = document.to_dict(flatten=False)
@@ -58,7 +57,7 @@ def convert_id(_id: str) -> str:
58
57
  return uuid.uuid5(UUID_NAMESPACE, _id).hex
59
58
 
60
59
 
61
- QdrantPoint = Union[rest.ScoredPoint, rest.Record]
60
+ QdrantPoint = rest.ScoredPoint | rest.Record
62
61
 
63
62
 
64
63
  def convert_qdrant_point_to_haystack_document(point: QdrantPoint, use_sparse_embeddings: bool) -> Document: