cognee-community-vector-adapter-qdrant 0.0.2__py3-none-any.whl → 0.1.0__py3-none-any.whl

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.
@@ -1,3 +1,3 @@
1
1
  from .qdrant_adapter import QDrantAdapter
2
2
 
3
- __all__ = ["QDrantAdapter"]
3
+ __all__ = ["QDrantAdapter"]
@@ -1,16 +1,16 @@
1
1
  import asyncio
2
- from typing import Dict, List, Optional
3
- from qdrant_client import AsyncQdrantClient, models
4
-
5
- from cognee.exceptions import InvalidValueError
6
- from cognee.shared.logging_utils import get_logger
7
2
 
8
- from cognee.infrastructure.engine import DataPoint
9
- from cognee.infrastructure.engine.utils import parse_id
3
+ from cognee.infrastructure.databases.exceptions import MissingQueryParameterError
10
4
  from cognee.infrastructure.databases.vector import VectorDBInterface
11
- from cognee.infrastructure.databases.vector.models.ScoredResult import ScoredResult
12
- from cognee.infrastructure.databases.vector.embeddings.EmbeddingEngine import EmbeddingEngine
5
+ from cognee.infrastructure.databases.vector.embeddings.EmbeddingEngine import (
6
+ EmbeddingEngine,
7
+ )
13
8
  from cognee.infrastructure.databases.vector.exceptions import CollectionNotFoundError
9
+ from cognee.infrastructure.databases.vector.models.ScoredResult import ScoredResult
10
+ from cognee.infrastructure.engine import DataPoint
11
+ from cognee.infrastructure.engine.utils import parse_id
12
+ from cognee.shared.logging_utils import get_logger
13
+ from qdrant_client import AsyncQdrantClient, models
14
14
 
15
15
  logger = get_logger("QDrantAdapter")
16
16
 
@@ -21,20 +21,19 @@ class IndexSchema(DataPoint):
21
21
  metadata: dict = {"index_fields": ["text"]}
22
22
 
23
23
 
24
-
25
- def create_hnsw_config(hnsw_config: Dict):
24
+ def create_hnsw_config(hnsw_config: dict):
26
25
  if hnsw_config is not None:
27
26
  return models.HnswConfig()
28
27
  return None
29
28
 
30
29
 
31
- def create_optimizers_config(optimizers_config: Dict):
30
+ def create_optimizers_config(optimizers_config: dict):
32
31
  if optimizers_config is not None:
33
32
  return models.OptimizersConfig()
34
33
  return None
35
34
 
36
35
 
37
- def create_quantization_config(quantization_config: Dict):
36
+ def create_quantization_config(quantization_config: dict):
38
37
  if quantization_config is not None:
39
38
  return models.QuantizationConfig()
40
39
  return None
@@ -64,7 +63,7 @@ class QDrantAdapter(VectorDBInterface):
64
63
 
65
64
  return AsyncQdrantClient(location=":memory:")
66
65
 
67
- async def embed_data(self, data: List[str]) -> List[float]:
66
+ async def embed_data(self, data: list[str]) -> list[float]:
68
67
  return await self.embedding_engine.embed_text(data)
69
68
 
70
69
  async def has_collection(self, collection_name: str) -> bool:
@@ -86,14 +85,15 @@ class QDrantAdapter(VectorDBInterface):
86
85
  collection_name=collection_name,
87
86
  vectors_config={
88
87
  "text": models.VectorParams(
89
- size=self.embedding_engine.get_vector_size(), distance="Cosine"
88
+ size=self.embedding_engine.get_vector_size(),
89
+ distance="Cosine",
90
90
  )
91
91
  },
92
92
  )
93
93
 
94
94
  await client.close()
95
95
 
96
- async def create_data_points(self, collection_name: str, data_points: List[DataPoint]):
96
+ async def create_data_points(self, collection_name: str, data_points: list[DataPoint]):
97
97
  from qdrant_client.http.exceptions import UnexpectedResponse
98
98
 
99
99
  client = self.get_qdrant_client()
@@ -112,7 +112,8 @@ class QDrantAdapter(VectorDBInterface):
112
112
  points = [convert_to_qdrant_point(point) for point in data_points]
113
113
 
114
114
  try:
115
- client.upload_points(collection_name=collection_name, points=points)
115
+ # Use upsert for AsyncQdrantClient (upload_points doesn't exist or is sync)
116
+ await client.upsert(collection_name=collection_name, points=points)
116
117
  except UnexpectedResponse as error:
117
118
  if "Collection not found" in str(error):
118
119
  raise CollectionNotFoundError(
@@ -152,15 +153,13 @@ class QDrantAdapter(VectorDBInterface):
152
153
  async def search(
153
154
  self,
154
155
  collection_name: str,
155
- query_text: Optional[str] = None,
156
- query_vector: Optional[List[float]] = None,
157
- limit: int = 15,
156
+ query_text: str | None = None,
157
+ query_vector: list[float] | None = None,
158
+ limit: int | None = 15,
158
159
  with_vector: bool = False,
159
- ) -> List[ScoredResult]:
160
- from qdrant_client.http.exceptions import UnexpectedResponse
161
-
160
+ ) -> list[ScoredResult]:
162
161
  if query_text is None and query_vector is None:
163
- raise InvalidValueError(message="One of query_text or query_vector must be provided!")
162
+ raise MissingQueryParameterError()
164
163
 
165
164
  if not await self.has_collection(collection_name):
166
165
  return []
@@ -168,44 +167,53 @@ class QDrantAdapter(VectorDBInterface):
168
167
  if query_vector is None:
169
168
  query_vector = (await self.embed_data([query_text]))[0]
170
169
 
170
+ client = None
171
171
  try:
172
172
  client = self.get_qdrant_client()
173
- if limit == 0:
173
+ if limit is None:
174
174
  collection_size = await client.count(collection_name=collection_name)
175
+ limit = collection_size.count
176
+ if limit == 0:
177
+ await client.close()
178
+ return []
175
179
 
176
- results = await client.search(
180
+ # Use query_points instead of search (API change in qdrant-client)
181
+ # query_points is the correct method for AsyncQdrantClient
182
+ query_result = await client.query_points(
177
183
  collection_name=collection_name,
178
- query_vector=models.NamedVector(
179
- name="text",
180
- vector=query_vector
181
- if query_vector is not None
182
- else (await self.embed_data([query_text]))[0],
183
- ),
184
- limit=limit if limit > 0 else collection_size.count,
184
+ query=query_vector,
185
+ using="text",
186
+ limit=limit,
185
187
  with_vectors=with_vector,
186
188
  )
187
189
 
188
190
  await client.close()
189
191
 
192
+ # Extract points from query_result
193
+ results = query_result.points
194
+
190
195
  return [
191
196
  ScoredResult(
192
- id=parse_id(result.id),
197
+ id=parse_id(str(result.id)),
193
198
  payload={
194
199
  **result.payload,
195
- "id": parse_id(result.id),
200
+ "id": parse_id(str(result.id)),
196
201
  },
197
- score=1 - result.score,
202
+ score=1 - result.score if hasattr(result, 'score') else 1.0,
198
203
  )
199
204
  for result in results
200
205
  ]
201
- finally:
202
- await client.close()
206
+ except Exception as e:
207
+ logger.error(f"Error in Qdrant search: {e}", exc_info=True)
208
+ if client:
209
+ await client.close()
210
+ return []
203
211
 
204
212
  async def batch_search(
205
213
  self,
206
214
  collection_name: str,
207
- query_texts: List[str],
208
- limit: int = None,
215
+ query_texts: list[str],
216
+ limit: int | None = None,
209
217
  with_vectors: bool = False,
210
218
  ):
211
219
  """
@@ -215,32 +223,50 @@ class QDrantAdapter(VectorDBInterface):
215
223
  - collection_name (str): Name of the collection to search in.
216
224
  - query_texts (List[str]): List of query texts to search for.
217
225
  - limit (int): List of result limits for search requests.
218
- - with_vectors (bool, optional): Bool indicating whether to return vectors for search requests.
226
+ - with_vectors (bool, optional): Bool indicating whether to return
227
+ vectors for search requests.
219
228
 
220
229
  Returns:
221
230
  - results: The search results from Qdrant.
222
231
  """
223
232
 
224
- vectors = await self.embed_data(query_texts)
225
-
226
- # Generate dynamic search requests based on the provided embeddings
227
- requests = [
228
- models.SearchRequest(
229
- vector=models.NamedVector(name="text", vector=vector),
230
- limit=limit,
231
- with_vector=with_vectors,
232
- )
233
- for vector in vectors
234
- ]
233
+ client = self.get_qdrant_client()
234
+ if limit is None:
235
+ collection_size = await client.count(collection_name=collection_name)
236
+ limit = collection_size.count
237
+ if limit == 0:
238
+ await client.close()
239
+ return []
235
240
 
236
241
  client = self.get_qdrant_client()
237
242
 
238
- # Perform batch search with the dynamically generated requests
239
- results = await client.search_batch(collection_name=collection_name, requests=requests)
243
+ try:
244
+ # Use query_batch instead of search_batch (API change in qdrant-client)
245
+ # query_batch is the correct method for AsyncQdrantClient
246
+ query_results = await client.query_batch(
247
+ collection_name=collection_name,
248
+ query_texts=query_texts,
249
+ limit=limit,
250
+ with_vectors=with_vectors,
251
+ )
240
252
 
241
- await client.close()
253
+ await client.close()
242
254
 
243
- return [filter(lambda result: result.score > 0.9, result_group) for result_group in results]
255
+ # Extract points from each query result and filter by score
256
+ filtered_results = []
257
+ for query_result in query_results:
258
+ points = query_result.points if hasattr(query_result, 'points') else []
259
+ filtered_points = [
260
+ result for result in points
261
+ if hasattr(result, 'score') and result.score > 0.9
262
+ ]
263
+ filtered_results.append(filtered_points)
264
+
265
+ return filtered_results
266
+ except Exception as e:
267
+ logger.error(f"Error in Qdrant batch_search: {e}", exc_info=True)
268
+ await client.close()
269
+ return []
244
270
 
245
271
  async def delete_data_points(self, collection_name: str, data_point_ids: list[str]):
246
272
  client = self.get_qdrant_client()
@@ -256,3 +282,21 @@ class QDrantAdapter(VectorDBInterface):
256
282
  await client.delete_collection(collection.name)
257
283
 
258
284
  await client.close()
285
+
286
+ async def get_collection_names(self) -> list[str]:
287
+ """
288
+ Get names of all collections in the database.
289
+
290
+ Returns:
291
+ list[str]: List of collection names.
292
+ """
293
+
294
+ client = self.get_qdrant_client()
295
+
296
+ response = await client.get_collections()
297
+
298
+ result = [collection.name for collection in response.collections]
299
+
300
+ await client.close()
301
+
302
+ return result
@@ -0,0 +1,54 @@
1
+ Metadata-Version: 2.4
2
+ Name: cognee-community-vector-adapter-qdrant
3
+ Version: 0.1.0
4
+ Summary: Qdrant vector database adapter for cognee
5
+ Requires-Python: >=3.11,<=3.13
6
+ Classifier: Programming Language :: Python :: 3
7
+ Classifier: Programming Language :: Python :: 3.11
8
+ Classifier: Programming Language :: Python :: 3.12
9
+ Classifier: Programming Language :: Python :: 3.13
10
+ Requires-Dist: cognee (>=0.4.0)
11
+ Requires-Dist: instructor (>=1.11)
12
+ Requires-Dist: qdrant-client (>=1.16.0)
13
+ Requires-Dist: starlette (>=0.48.0)
14
+ Description-Content-Type: text/markdown
15
+
16
+ # Cognee Qdrant Adapter
17
+
18
+ ## Installation
19
+
20
+ If published, the package can be simply installed via pip:
21
+
22
+ ```bash
23
+ pip install cognee-community-vector-adapter-qdrant
24
+ ```
25
+
26
+ In case it is not published yet, you can use poetry to locally build the adapter package:
27
+
28
+ ```bash
29
+ pip install poetry
30
+ poetry install # run this command in the directory containing the pyproject.toml file
31
+ ```
32
+
33
+ ## Connection Setup
34
+
35
+ For a quick local setup, you can run a docker container that qdrant provides (https://qdrant.tech/documentation/quickstart/).
36
+ After this, you will be able to connect to the Qdrant DB through the appropriate ports. The command for running the docker
37
+ container looks something like the following:
38
+
39
+ ```
40
+ docker run -p 6333:6333 -p 6334:6334 \
41
+ -v "$(pwd)/qdrant_storage:/qdrant/storage:z" \
42
+ qdrant/qdrant
43
+ ```
44
+
45
+ ## Usage
46
+
47
+ Import and register the adapter in your code:
48
+ ```python
49
+ from cognee_community_vector_adapter_qdrant import register
50
+ ```
51
+
52
+ ## Example
53
+ See example in `example.py` file.
54
+
@@ -0,0 +1,6 @@
1
+ cognee_community_vector_adapter_qdrant/__init__.py,sha256=OYsRMTyBnNuusKB3rkQmwCppfdEf__AuXMw_Ma1k6lQ,71
2
+ cognee_community_vector_adapter_qdrant/qdrant_adapter.py,sha256=hFMmSaUArnhTZHR8I9VW3fHdmO-1VHw8TD9-fJ4rs-c,10379
3
+ cognee_community_vector_adapter_qdrant/register.py,sha256=K0cIQGN3an79wWCMXAIgwsymkloHGV2_joy7G-4aiB8,158
4
+ cognee_community_vector_adapter_qdrant-0.1.0.dist-info/METADATA,sha256=0dcxsPnOFHs-gDGnrmFJR9up07mdE6AAQ7tkvRhnPbA,1537
5
+ cognee_community_vector_adapter_qdrant-0.1.0.dist-info/WHEEL,sha256=zp0Cn7JsFoX2ATtOhtaFYIiE2rmFAD4OcMhtUki8W3U,88
6
+ cognee_community_vector_adapter_qdrant-0.1.0.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: poetry-core 2.1.2
2
+ Generator: poetry-core 2.2.1
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
@@ -1,28 +0,0 @@
1
- Metadata-Version: 2.3
2
- Name: cognee-community-vector-adapter-qdrant
3
- Version: 0.0.2
4
- Summary: Qdrant vector database adapter for cognee
5
- Requires-Python: >=3.11,<=3.13
6
- Classifier: Programming Language :: Python :: 3
7
- Classifier: Programming Language :: Python :: 3.11
8
- Classifier: Programming Language :: Python :: 3.12
9
- Classifier: Programming Language :: Python :: 3.13
10
- Requires-Dist: cognee (>=0.2.1)
11
- Requires-Dist: qdrant-client (>=1.14.2)
12
- Description-Content-Type: text/markdown
13
-
14
- # Cognee Qdrant Adapter
15
-
16
- ## Install
17
-
18
- Install [`qdrant-client`](https://pypi.org/project/qdrant-client/) in your project.
19
-
20
- Put this line of code somewhere at the start of the execution, before cognee is initiated.
21
-
22
- ```python
23
- import packages.vector.qdrant.register
24
- ```
25
-
26
- ## Example
27
- See example in `example.py` file.
28
-
@@ -1,6 +0,0 @@
1
- cognee_community_vector_adapter_qdrant/__init__.py,sha256=PVY2CqYr0JnjErQoDSEobMol0M2BwZFnSOppfJq1cHs,71
2
- cognee_community_vector_adapter_qdrant/qdrant_adapter.py,sha256=TFUSVVrXy-0DZxu-DgjUuPIzvqSaaFvFyt_-pRPKCKQ,8858
3
- cognee_community_vector_adapter_qdrant/register.py,sha256=K0cIQGN3an79wWCMXAIgwsymkloHGV2_joy7G-4aiB8,158
4
- cognee_community_vector_adapter_qdrant-0.0.2.dist-info/METADATA,sha256=UZdDQQJITyPWanHHP-N322-aXVxjRxikua-Yg2reVsA,792
5
- cognee_community_vector_adapter_qdrant-0.0.2.dist-info/WHEEL,sha256=fGIA9gx4Qxk2KDKeNJCbOEwSrmLtjWCwzBz351GyrPQ,88
6
- cognee_community_vector_adapter_qdrant-0.0.2.dist-info/RECORD,,