sf-vector-sdk 0.2.0__py3-none-any.whl → 0.2.3__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.
@@ -151,26 +151,21 @@ class SearchNamespace(BaseNamespace):
151
151
  Raises:
152
152
  TimeoutError: If no result is received within the timeout
153
153
  """
154
- channel = f"query:result:{request_id}"
155
- pubsub = self._redis.pubsub()
156
- pubsub.subscribe(channel)
157
-
158
- try:
159
- start_time = datetime.utcnow()
160
- while True:
161
- message = pubsub.get_message(timeout=1.0)
162
- if message and message["type"] == "message":
163
- data = json.loads(message["data"])
164
- return QueryResult.from_dict(data)
165
-
166
- elapsed = (datetime.utcnow() - start_time).total_seconds()
167
- if elapsed >= timeout:
168
- raise TimeoutError(
169
- f"No query result received for {request_id} within {timeout}s"
170
- )
171
- finally:
172
- pubsub.unsubscribe(channel)
173
- pubsub.close()
154
+ list_key = f"query:response:{request_id}"
155
+
156
+ # BRPOP blocks until result is available or timeout
157
+ result = self._redis.brpop(list_key, timeout=timeout)
158
+
159
+ if result is None:
160
+ raise TimeoutError(
161
+ f"No query result received for {request_id} within {timeout}s"
162
+ )
163
+
164
+ # result = (key, value)
165
+ data = json.loads(result[1])
166
+ # Cleanup the response list
167
+ self._redis.delete(list_key)
168
+ return QueryResult.from_dict(data)
174
169
 
175
170
  def query_and_wait(
176
171
  self,
@@ -193,8 +188,8 @@ class SearchNamespace(BaseNamespace):
193
188
  """
194
189
  Submit a search query and wait for the result.
195
190
 
196
- This method subscribes to the result channel BEFORE submitting the request,
197
- ensuring no race condition where the result is published before we're listening.
191
+ Uses BRPOP for efficient blocking wait - no race condition since the result
192
+ is pushed to a list that persists until consumed.
198
193
 
199
194
  Args:
200
195
  query_text: The text to search for
@@ -217,42 +212,25 @@ class SearchNamespace(BaseNamespace):
217
212
  The query result
218
213
  """
219
214
  request_id = str(uuid.uuid4())
220
- channel = f"query:result:{request_id}"
221
-
222
- pubsub = self._redis.pubsub()
223
- pubsub.subscribe(channel)
224
-
225
- try:
226
- self.query(
227
- query_text=query_text,
228
- database=database,
229
- top_k=top_k,
230
- min_score=min_score,
231
- filters=filters,
232
- namespace=namespace,
233
- collection=collection,
234
- database_name=database_name,
235
- include_vectors=include_vectors,
236
- include_metadata=include_metadata,
237
- embedding_model=embedding_model,
238
- embedding_dimensions=embedding_dimensions,
239
- priority=priority,
240
- metadata=metadata,
241
- request_id=request_id,
242
- )
243
215
 
244
- start_time = datetime.utcnow()
245
- while True:
246
- message = pubsub.get_message(timeout=1.0)
247
- if message and message["type"] == "message":
248
- data = json.loads(message["data"])
249
- return QueryResult.from_dict(data)
250
-
251
- elapsed = (datetime.utcnow() - start_time).total_seconds()
252
- if elapsed >= timeout:
253
- raise TimeoutError(
254
- f"No query result received for {request_id} within {timeout}s"
255
- )
256
- finally:
257
- pubsub.unsubscribe(channel)
258
- pubsub.close()
216
+ # Submit the request first
217
+ self.query(
218
+ query_text=query_text,
219
+ database=database,
220
+ top_k=top_k,
221
+ min_score=min_score,
222
+ filters=filters,
223
+ namespace=namespace,
224
+ collection=collection,
225
+ database_name=database_name,
226
+ include_vectors=include_vectors,
227
+ include_metadata=include_metadata,
228
+ embedding_model=embedding_model,
229
+ embedding_dimensions=embedding_dimensions,
230
+ priority=priority,
231
+ metadata=metadata,
232
+ request_id=request_id,
233
+ )
234
+
235
+ # Wait for result via BRPOP
236
+ return self.wait_for(request_id, timeout)
@@ -14,9 +14,15 @@ from .router import (
14
14
  validate_database_routing,
15
15
  )
16
16
  from .structured_embeddings import (
17
+ AudioRecapBatchItem,
18
+ BatchItem,
19
+ FlashCardBatchItem,
17
20
  StructuredEmbeddingsNamespace,
21
+ TestQuestionBatchItem,
18
22
  TestQuestionInput,
19
23
  ToolMetadata,
24
+ TopicBatchItem,
25
+ TopicMetadata,
20
26
  )
21
27
  from .tool_config import (
22
28
  TOOL_CONFIGS,
@@ -37,7 +43,14 @@ __all__ = [
37
43
  "StructuredEmbeddingsNamespace",
38
44
  # Types
39
45
  "ToolMetadata",
46
+ "TopicMetadata",
40
47
  "TestQuestionInput",
48
+ # Batch types
49
+ "BatchItem",
50
+ "FlashCardBatchItem",
51
+ "TestQuestionBatchItem",
52
+ "AudioRecapBatchItem",
53
+ "TopicBatchItem",
41
54
  # Tool configuration
42
55
  "ToolConfig",
43
56
  "ToolDatabaseConfig",