usecortex-ai 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.
Files changed (89) hide show
  1. cortex_ai/__init__.py +103 -0
  2. cortex_ai/client.py +244 -0
  3. cortex_ai/core/__init__.py +52 -0
  4. cortex_ai/core/api_error.py +23 -0
  5. cortex_ai/core/client_wrapper.py +84 -0
  6. cortex_ai/core/datetime_utils.py +28 -0
  7. cortex_ai/core/file.py +67 -0
  8. cortex_ai/core/force_multipart.py +18 -0
  9. cortex_ai/core/http_client.py +543 -0
  10. cortex_ai/core/http_response.py +55 -0
  11. cortex_ai/core/jsonable_encoder.py +100 -0
  12. cortex_ai/core/pydantic_utilities.py +258 -0
  13. cortex_ai/core/query_encoder.py +58 -0
  14. cortex_ai/core/remove_none_from_dict.py +11 -0
  15. cortex_ai/core/request_options.py +35 -0
  16. cortex_ai/core/serialization.py +276 -0
  17. cortex_ai/embeddings/__init__.py +4 -0
  18. cortex_ai/embeddings/client.py +442 -0
  19. cortex_ai/embeddings/raw_client.py +1153 -0
  20. cortex_ai/environment.py +7 -0
  21. cortex_ai/errors/__init__.py +21 -0
  22. cortex_ai/errors/bad_request_error.py +11 -0
  23. cortex_ai/errors/forbidden_error.py +11 -0
  24. cortex_ai/errors/internal_server_error.py +11 -0
  25. cortex_ai/errors/not_found_error.py +11 -0
  26. cortex_ai/errors/service_unavailable_error.py +11 -0
  27. cortex_ai/errors/unauthorized_error.py +11 -0
  28. cortex_ai/errors/unprocessable_entity_error.py +10 -0
  29. cortex_ai/fetch/__init__.py +4 -0
  30. cortex_ai/fetch/client.py +143 -0
  31. cortex_ai/fetch/raw_client.py +310 -0
  32. cortex_ai/raw_client.py +90 -0
  33. cortex_ai/search/__init__.py +7 -0
  34. cortex_ai/search/client.py +536 -0
  35. cortex_ai/search/raw_client.py +1064 -0
  36. cortex_ai/search/types/__init__.py +7 -0
  37. cortex_ai/search/types/alpha.py +5 -0
  38. cortex_ai/sources/__init__.py +4 -0
  39. cortex_ai/sources/client.py +187 -0
  40. cortex_ai/sources/raw_client.py +532 -0
  41. cortex_ai/tenant/__init__.py +4 -0
  42. cortex_ai/tenant/client.py +120 -0
  43. cortex_ai/tenant/raw_client.py +283 -0
  44. cortex_ai/types/__init__.py +69 -0
  45. cortex_ai/types/actual_error_response.py +20 -0
  46. cortex_ai/types/app_sources_upload_data.py +22 -0
  47. cortex_ai/types/attachment_model.py +26 -0
  48. cortex_ai/types/batch_upload_data.py +22 -0
  49. cortex_ai/types/bm_25_operator_type.py +5 -0
  50. cortex_ai/types/content_model.py +26 -0
  51. cortex_ai/types/delete_memory_request.py +21 -0
  52. cortex_ai/types/embeddings_create_collection_data.py +22 -0
  53. cortex_ai/types/embeddings_delete_data.py +22 -0
  54. cortex_ai/types/embeddings_get_data.py +22 -0
  55. cortex_ai/types/embeddings_search_data.py +22 -0
  56. cortex_ai/types/error_response.py +22 -0
  57. cortex_ai/types/extended_context.py +20 -0
  58. cortex_ai/types/fetch_content_data.py +23 -0
  59. cortex_ai/types/file_upload_result.py +20 -0
  60. cortex_ai/types/full_text_search_data.py +22 -0
  61. cortex_ai/types/http_validation_error.py +20 -0
  62. cortex_ai/types/list_sources_response.py +22 -0
  63. cortex_ai/types/markdown_upload_request.py +21 -0
  64. cortex_ai/types/processing_status.py +22 -0
  65. cortex_ai/types/related_chunk.py +22 -0
  66. cortex_ai/types/search_chunk.py +34 -0
  67. cortex_ai/types/search_data.py +22 -0
  68. cortex_ai/types/single_upload_data.py +21 -0
  69. cortex_ai/types/source.py +32 -0
  70. cortex_ai/types/source_content.py +26 -0
  71. cortex_ai/types/source_model.py +32 -0
  72. cortex_ai/types/tenant_create_data.py +22 -0
  73. cortex_ai/types/tenant_stats.py +23 -0
  74. cortex_ai/types/validation_error.py +22 -0
  75. cortex_ai/types/validation_error_loc_item.py +5 -0
  76. cortex_ai/upload/__init__.py +4 -0
  77. cortex_ai/upload/client.py +1572 -0
  78. cortex_ai/upload/raw_client.py +4202 -0
  79. cortex_ai/user/__init__.py +4 -0
  80. cortex_ai/user/client.py +125 -0
  81. cortex_ai/user/raw_client.py +300 -0
  82. cortex_ai/user_memory/__init__.py +4 -0
  83. cortex_ai/user_memory/client.py +443 -0
  84. cortex_ai/user_memory/raw_client.py +651 -0
  85. usecortex_ai-0.1.0.dist-info/METADATA +136 -0
  86. usecortex_ai-0.1.0.dist-info/RECORD +89 -0
  87. usecortex_ai-0.1.0.dist-info/WHEEL +5 -0
  88. usecortex_ai-0.1.0.dist-info/licenses/LICENSE +22 -0
  89. usecortex_ai-0.1.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,1153 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ import typing
4
+ from json.decoder import JSONDecodeError
5
+
6
+ from ..core.api_error import ApiError
7
+ from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
8
+ from ..core.http_response import AsyncHttpResponse, HttpResponse
9
+ from ..core.pydantic_utilities import parse_obj_as
10
+ from ..core.request_options import RequestOptions
11
+ from ..errors.bad_request_error import BadRequestError
12
+ from ..errors.forbidden_error import ForbiddenError
13
+ from ..errors.internal_server_error import InternalServerError
14
+ from ..errors.not_found_error import NotFoundError
15
+ from ..errors.service_unavailable_error import ServiceUnavailableError
16
+ from ..errors.unauthorized_error import UnauthorizedError
17
+ from ..errors.unprocessable_entity_error import UnprocessableEntityError
18
+ from ..types.actual_error_response import ActualErrorResponse
19
+ from ..types.embeddings_create_collection_data import EmbeddingsCreateCollectionData
20
+ from ..types.embeddings_delete_data import EmbeddingsDeleteData
21
+ from ..types.embeddings_get_data import EmbeddingsGetData
22
+ from ..types.embeddings_search_data import EmbeddingsSearchData
23
+
24
+ # this is used as the default value for optional parameters
25
+ OMIT = typing.cast(typing.Any, ...)
26
+
27
+
28
+ class RawEmbeddingsClient:
29
+ def __init__(self, *, client_wrapper: SyncClientWrapper):
30
+ self._client_wrapper = client_wrapper
31
+
32
+ def delete(
33
+ self,
34
+ *,
35
+ chunk_ids: typing.Sequence[str],
36
+ tenant_id: str,
37
+ sub_tenant_id: typing.Optional[str] = OMIT,
38
+ request_options: typing.Optional[RequestOptions] = None,
39
+ ) -> HttpResponse[EmbeddingsDeleteData]:
40
+ """
41
+ Delete specific embedding chunks from indexed sources.
42
+
43
+ This endpoint deletes specified embedding chunks from the Findr backend by sending
44
+ chunk IDs to the backend delete service.
45
+
46
+ Args:
47
+ request (EmbeddingsDeleteRequest): The delete request containing:
48
+ - chunk_ids (List[str]): List of chunk IDs to delete
49
+ - tenant_id (str): Tenant identifier for multi-tenancy
50
+ - sub_tenant_id (str, optional): Sub-tenant identifier, defaults to tenant_id
51
+ api_details (dict): Authentication details obtained from API key validation
52
+
53
+ Returns:
54
+ EmbeddingsDeleteData: Success response with deletion details
55
+
56
+ Parameters
57
+ ----------
58
+ chunk_ids : typing.Sequence[str]
59
+
60
+ tenant_id : str
61
+
62
+ sub_tenant_id : typing.Optional[str]
63
+
64
+ request_options : typing.Optional[RequestOptions]
65
+ Request-specific configuration.
66
+
67
+ Returns
68
+ -------
69
+ HttpResponse[EmbeddingsDeleteData]
70
+ Successful Response
71
+ """
72
+ _response = self._client_wrapper.httpx_client.request(
73
+ "embeddings/delete",
74
+ method="DELETE",
75
+ json={
76
+ "chunk_ids": chunk_ids,
77
+ "tenant_id": tenant_id,
78
+ "sub_tenant_id": sub_tenant_id,
79
+ },
80
+ headers={
81
+ "content-type": "application/json",
82
+ },
83
+ request_options=request_options,
84
+ omit=OMIT,
85
+ )
86
+ try:
87
+ if 200 <= _response.status_code < 300:
88
+ _data = typing.cast(
89
+ EmbeddingsDeleteData,
90
+ parse_obj_as(
91
+ type_=EmbeddingsDeleteData, # type: ignore
92
+ object_=_response.json(),
93
+ ),
94
+ )
95
+ return HttpResponse(response=_response, data=_data)
96
+ if _response.status_code == 400:
97
+ raise BadRequestError(
98
+ headers=dict(_response.headers),
99
+ body=typing.cast(
100
+ ActualErrorResponse,
101
+ parse_obj_as(
102
+ type_=ActualErrorResponse, # type: ignore
103
+ object_=_response.json(),
104
+ ),
105
+ ),
106
+ )
107
+ if _response.status_code == 401:
108
+ raise UnauthorizedError(
109
+ headers=dict(_response.headers),
110
+ body=typing.cast(
111
+ ActualErrorResponse,
112
+ parse_obj_as(
113
+ type_=ActualErrorResponse, # type: ignore
114
+ object_=_response.json(),
115
+ ),
116
+ ),
117
+ )
118
+ if _response.status_code == 403:
119
+ raise ForbiddenError(
120
+ headers=dict(_response.headers),
121
+ body=typing.cast(
122
+ ActualErrorResponse,
123
+ parse_obj_as(
124
+ type_=ActualErrorResponse, # type: ignore
125
+ object_=_response.json(),
126
+ ),
127
+ ),
128
+ )
129
+ if _response.status_code == 404:
130
+ raise NotFoundError(
131
+ headers=dict(_response.headers),
132
+ body=typing.cast(
133
+ ActualErrorResponse,
134
+ parse_obj_as(
135
+ type_=ActualErrorResponse, # type: ignore
136
+ object_=_response.json(),
137
+ ),
138
+ ),
139
+ )
140
+ if _response.status_code == 422:
141
+ raise UnprocessableEntityError(
142
+ headers=dict(_response.headers),
143
+ body=typing.cast(
144
+ typing.Optional[typing.Any],
145
+ parse_obj_as(
146
+ type_=typing.Optional[typing.Any], # type: ignore
147
+ object_=_response.json(),
148
+ ),
149
+ ),
150
+ )
151
+ if _response.status_code == 500:
152
+ raise InternalServerError(
153
+ headers=dict(_response.headers),
154
+ body=typing.cast(
155
+ ActualErrorResponse,
156
+ parse_obj_as(
157
+ type_=ActualErrorResponse, # type: ignore
158
+ object_=_response.json(),
159
+ ),
160
+ ),
161
+ )
162
+ if _response.status_code == 503:
163
+ raise ServiceUnavailableError(
164
+ headers=dict(_response.headers),
165
+ body=typing.cast(
166
+ ActualErrorResponse,
167
+ parse_obj_as(
168
+ type_=ActualErrorResponse, # type: ignore
169
+ object_=_response.json(),
170
+ ),
171
+ ),
172
+ )
173
+ _response_json = _response.json()
174
+ except JSONDecodeError:
175
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
176
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
177
+
178
+ def search(
179
+ self,
180
+ *,
181
+ embeddings: typing.Sequence[float],
182
+ tenant_id: str,
183
+ sub_tenant_id: typing.Optional[str] = OMIT,
184
+ max_chunks: typing.Optional[int] = OMIT,
185
+ request_options: typing.Optional[RequestOptions] = None,
186
+ ) -> HttpResponse[EmbeddingsSearchData]:
187
+ """
188
+ Search for similar embedding chunks using vector similarity.
189
+
190
+ This endpoint performs semantic search by sending an embedding vector to the Findr backend
191
+ and returns a list of the most similar chunk IDs based on vector similarity.
192
+
193
+ Args:
194
+ request (EmbeddingsSearchRequest): The search request containing:
195
+ - embeddings (List[float]): Single embedding vector for similarity search
196
+ - tenant_id (str): Tenant identifier for multi-tenancy
197
+ - sub_tenant_id (str, optional): Sub-tenant identifier, defaults to tenant_id
198
+ - max_chunks (int, optional): Maximum number of chunk IDs to return (default: 10)
199
+ api_details (dict): Authentication details obtained from API key validation
200
+
201
+ Returns:
202
+ EmbeddingsSearchData: List of chunk IDs with similarity scores
203
+
204
+ Parameters
205
+ ----------
206
+ embeddings : typing.Sequence[float]
207
+ Single embedding vector for search
208
+
209
+ tenant_id : str
210
+
211
+ sub_tenant_id : typing.Optional[str]
212
+
213
+ max_chunks : typing.Optional[int]
214
+
215
+ request_options : typing.Optional[RequestOptions]
216
+ Request-specific configuration.
217
+
218
+ Returns
219
+ -------
220
+ HttpResponse[EmbeddingsSearchData]
221
+ Successful Response
222
+ """
223
+ _response = self._client_wrapper.httpx_client.request(
224
+ "embeddings/search",
225
+ method="POST",
226
+ json={
227
+ "embeddings": embeddings,
228
+ "tenant_id": tenant_id,
229
+ "sub_tenant_id": sub_tenant_id,
230
+ "max_chunks": max_chunks,
231
+ },
232
+ headers={
233
+ "content-type": "application/json",
234
+ },
235
+ request_options=request_options,
236
+ omit=OMIT,
237
+ )
238
+ try:
239
+ if 200 <= _response.status_code < 300:
240
+ _data = typing.cast(
241
+ EmbeddingsSearchData,
242
+ parse_obj_as(
243
+ type_=EmbeddingsSearchData, # type: ignore
244
+ object_=_response.json(),
245
+ ),
246
+ )
247
+ return HttpResponse(response=_response, data=_data)
248
+ if _response.status_code == 400:
249
+ raise BadRequestError(
250
+ headers=dict(_response.headers),
251
+ body=typing.cast(
252
+ ActualErrorResponse,
253
+ parse_obj_as(
254
+ type_=ActualErrorResponse, # type: ignore
255
+ object_=_response.json(),
256
+ ),
257
+ ),
258
+ )
259
+ if _response.status_code == 401:
260
+ raise UnauthorizedError(
261
+ headers=dict(_response.headers),
262
+ body=typing.cast(
263
+ ActualErrorResponse,
264
+ parse_obj_as(
265
+ type_=ActualErrorResponse, # type: ignore
266
+ object_=_response.json(),
267
+ ),
268
+ ),
269
+ )
270
+ if _response.status_code == 403:
271
+ raise ForbiddenError(
272
+ headers=dict(_response.headers),
273
+ body=typing.cast(
274
+ ActualErrorResponse,
275
+ parse_obj_as(
276
+ type_=ActualErrorResponse, # type: ignore
277
+ object_=_response.json(),
278
+ ),
279
+ ),
280
+ )
281
+ if _response.status_code == 404:
282
+ raise NotFoundError(
283
+ headers=dict(_response.headers),
284
+ body=typing.cast(
285
+ ActualErrorResponse,
286
+ parse_obj_as(
287
+ type_=ActualErrorResponse, # type: ignore
288
+ object_=_response.json(),
289
+ ),
290
+ ),
291
+ )
292
+ if _response.status_code == 422:
293
+ raise UnprocessableEntityError(
294
+ headers=dict(_response.headers),
295
+ body=typing.cast(
296
+ typing.Optional[typing.Any],
297
+ parse_obj_as(
298
+ type_=typing.Optional[typing.Any], # type: ignore
299
+ object_=_response.json(),
300
+ ),
301
+ ),
302
+ )
303
+ if _response.status_code == 500:
304
+ raise InternalServerError(
305
+ headers=dict(_response.headers),
306
+ body=typing.cast(
307
+ ActualErrorResponse,
308
+ parse_obj_as(
309
+ type_=ActualErrorResponse, # type: ignore
310
+ object_=_response.json(),
311
+ ),
312
+ ),
313
+ )
314
+ if _response.status_code == 503:
315
+ raise ServiceUnavailableError(
316
+ headers=dict(_response.headers),
317
+ body=typing.cast(
318
+ ActualErrorResponse,
319
+ parse_obj_as(
320
+ type_=ActualErrorResponse, # type: ignore
321
+ object_=_response.json(),
322
+ ),
323
+ ),
324
+ )
325
+ _response_json = _response.json()
326
+ except JSONDecodeError:
327
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
328
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
329
+
330
+ def get_by_chunk_ids(
331
+ self,
332
+ *,
333
+ chunk_ids: typing.Sequence[str],
334
+ tenant_id: str,
335
+ sub_tenant_id: typing.Optional[str] = OMIT,
336
+ request_options: typing.Optional[RequestOptions] = None,
337
+ ) -> HttpResponse[EmbeddingsGetData]:
338
+ """
339
+ Get embeddings based on chunk IDs.
340
+
341
+ This endpoint returns embeddings for a list of chunk IDs.
342
+
343
+ Returns:
344
+ EmbeddingsGetData: Embeddings data for the requested chunk IDs
345
+
346
+ Parameters
347
+ ----------
348
+ chunk_ids : typing.Sequence[str]
349
+
350
+ tenant_id : str
351
+
352
+ sub_tenant_id : typing.Optional[str]
353
+
354
+ request_options : typing.Optional[RequestOptions]
355
+ Request-specific configuration.
356
+
357
+ Returns
358
+ -------
359
+ HttpResponse[EmbeddingsGetData]
360
+ Successful Response
361
+ """
362
+ _response = self._client_wrapper.httpx_client.request(
363
+ "embeddings/by-chunk-ids",
364
+ method="POST",
365
+ json={
366
+ "chunk_ids": chunk_ids,
367
+ "tenant_id": tenant_id,
368
+ "sub_tenant_id": sub_tenant_id,
369
+ },
370
+ headers={
371
+ "content-type": "application/json",
372
+ },
373
+ request_options=request_options,
374
+ omit=OMIT,
375
+ )
376
+ try:
377
+ if 200 <= _response.status_code < 300:
378
+ _data = typing.cast(
379
+ EmbeddingsGetData,
380
+ parse_obj_as(
381
+ type_=EmbeddingsGetData, # type: ignore
382
+ object_=_response.json(),
383
+ ),
384
+ )
385
+ return HttpResponse(response=_response, data=_data)
386
+ if _response.status_code == 400:
387
+ raise BadRequestError(
388
+ headers=dict(_response.headers),
389
+ body=typing.cast(
390
+ ActualErrorResponse,
391
+ parse_obj_as(
392
+ type_=ActualErrorResponse, # type: ignore
393
+ object_=_response.json(),
394
+ ),
395
+ ),
396
+ )
397
+ if _response.status_code == 401:
398
+ raise UnauthorizedError(
399
+ headers=dict(_response.headers),
400
+ body=typing.cast(
401
+ ActualErrorResponse,
402
+ parse_obj_as(
403
+ type_=ActualErrorResponse, # type: ignore
404
+ object_=_response.json(),
405
+ ),
406
+ ),
407
+ )
408
+ if _response.status_code == 403:
409
+ raise ForbiddenError(
410
+ headers=dict(_response.headers),
411
+ body=typing.cast(
412
+ ActualErrorResponse,
413
+ parse_obj_as(
414
+ type_=ActualErrorResponse, # type: ignore
415
+ object_=_response.json(),
416
+ ),
417
+ ),
418
+ )
419
+ if _response.status_code == 404:
420
+ raise NotFoundError(
421
+ headers=dict(_response.headers),
422
+ body=typing.cast(
423
+ ActualErrorResponse,
424
+ parse_obj_as(
425
+ type_=ActualErrorResponse, # type: ignore
426
+ object_=_response.json(),
427
+ ),
428
+ ),
429
+ )
430
+ if _response.status_code == 422:
431
+ raise UnprocessableEntityError(
432
+ headers=dict(_response.headers),
433
+ body=typing.cast(
434
+ typing.Optional[typing.Any],
435
+ parse_obj_as(
436
+ type_=typing.Optional[typing.Any], # type: ignore
437
+ object_=_response.json(),
438
+ ),
439
+ ),
440
+ )
441
+ if _response.status_code == 500:
442
+ raise InternalServerError(
443
+ headers=dict(_response.headers),
444
+ body=typing.cast(
445
+ ActualErrorResponse,
446
+ parse_obj_as(
447
+ type_=ActualErrorResponse, # type: ignore
448
+ object_=_response.json(),
449
+ ),
450
+ ),
451
+ )
452
+ if _response.status_code == 503:
453
+ raise ServiceUnavailableError(
454
+ headers=dict(_response.headers),
455
+ body=typing.cast(
456
+ ActualErrorResponse,
457
+ parse_obj_as(
458
+ type_=ActualErrorResponse, # type: ignore
459
+ object_=_response.json(),
460
+ ),
461
+ ),
462
+ )
463
+ _response_json = _response.json()
464
+ except JSONDecodeError:
465
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
466
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
467
+
468
+ def create_collection(
469
+ self, *, tenant_id: str, request_options: typing.Optional[RequestOptions] = None
470
+ ) -> HttpResponse[EmbeddingsCreateCollectionData]:
471
+ """
472
+ Create an embeddings collection for the given tenant in Findr.
473
+
474
+ sub_tenant_id is set to be the same as tenant_id as per requirements.
475
+
476
+ Returns:
477
+ EmbeddingsCreateCollectionData: Success response with collection details
478
+
479
+ Parameters
480
+ ----------
481
+ tenant_id : str
482
+
483
+ request_options : typing.Optional[RequestOptions]
484
+ Request-specific configuration.
485
+
486
+ Returns
487
+ -------
488
+ HttpResponse[EmbeddingsCreateCollectionData]
489
+ Successful Response
490
+ """
491
+ _response = self._client_wrapper.httpx_client.request(
492
+ "embeddings/create_embeddings_tenant",
493
+ method="POST",
494
+ params={
495
+ "tenant_id": tenant_id,
496
+ },
497
+ request_options=request_options,
498
+ )
499
+ try:
500
+ if 200 <= _response.status_code < 300:
501
+ _data = typing.cast(
502
+ EmbeddingsCreateCollectionData,
503
+ parse_obj_as(
504
+ type_=EmbeddingsCreateCollectionData, # type: ignore
505
+ object_=_response.json(),
506
+ ),
507
+ )
508
+ return HttpResponse(response=_response, data=_data)
509
+ if _response.status_code == 400:
510
+ raise BadRequestError(
511
+ headers=dict(_response.headers),
512
+ body=typing.cast(
513
+ ActualErrorResponse,
514
+ parse_obj_as(
515
+ type_=ActualErrorResponse, # type: ignore
516
+ object_=_response.json(),
517
+ ),
518
+ ),
519
+ )
520
+ if _response.status_code == 401:
521
+ raise UnauthorizedError(
522
+ headers=dict(_response.headers),
523
+ body=typing.cast(
524
+ ActualErrorResponse,
525
+ parse_obj_as(
526
+ type_=ActualErrorResponse, # type: ignore
527
+ object_=_response.json(),
528
+ ),
529
+ ),
530
+ )
531
+ if _response.status_code == 403:
532
+ raise ForbiddenError(
533
+ headers=dict(_response.headers),
534
+ body=typing.cast(
535
+ ActualErrorResponse,
536
+ parse_obj_as(
537
+ type_=ActualErrorResponse, # type: ignore
538
+ object_=_response.json(),
539
+ ),
540
+ ),
541
+ )
542
+ if _response.status_code == 404:
543
+ raise NotFoundError(
544
+ headers=dict(_response.headers),
545
+ body=typing.cast(
546
+ ActualErrorResponse,
547
+ parse_obj_as(
548
+ type_=ActualErrorResponse, # type: ignore
549
+ object_=_response.json(),
550
+ ),
551
+ ),
552
+ )
553
+ if _response.status_code == 422:
554
+ raise UnprocessableEntityError(
555
+ headers=dict(_response.headers),
556
+ body=typing.cast(
557
+ typing.Optional[typing.Any],
558
+ parse_obj_as(
559
+ type_=typing.Optional[typing.Any], # type: ignore
560
+ object_=_response.json(),
561
+ ),
562
+ ),
563
+ )
564
+ if _response.status_code == 500:
565
+ raise InternalServerError(
566
+ headers=dict(_response.headers),
567
+ body=typing.cast(
568
+ ActualErrorResponse,
569
+ parse_obj_as(
570
+ type_=ActualErrorResponse, # type: ignore
571
+ object_=_response.json(),
572
+ ),
573
+ ),
574
+ )
575
+ if _response.status_code == 503:
576
+ raise ServiceUnavailableError(
577
+ headers=dict(_response.headers),
578
+ body=typing.cast(
579
+ ActualErrorResponse,
580
+ parse_obj_as(
581
+ type_=ActualErrorResponse, # type: ignore
582
+ object_=_response.json(),
583
+ ),
584
+ ),
585
+ )
586
+ _response_json = _response.json()
587
+ except JSONDecodeError:
588
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
589
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
590
+
591
+
592
+ class AsyncRawEmbeddingsClient:
593
+ def __init__(self, *, client_wrapper: AsyncClientWrapper):
594
+ self._client_wrapper = client_wrapper
595
+
596
+ async def delete(
597
+ self,
598
+ *,
599
+ chunk_ids: typing.Sequence[str],
600
+ tenant_id: str,
601
+ sub_tenant_id: typing.Optional[str] = OMIT,
602
+ request_options: typing.Optional[RequestOptions] = None,
603
+ ) -> AsyncHttpResponse[EmbeddingsDeleteData]:
604
+ """
605
+ Delete specific embedding chunks from indexed sources.
606
+
607
+ This endpoint deletes specified embedding chunks from the Findr backend by sending
608
+ chunk IDs to the backend delete service.
609
+
610
+ Args:
611
+ request (EmbeddingsDeleteRequest): The delete request containing:
612
+ - chunk_ids (List[str]): List of chunk IDs to delete
613
+ - tenant_id (str): Tenant identifier for multi-tenancy
614
+ - sub_tenant_id (str, optional): Sub-tenant identifier, defaults to tenant_id
615
+ api_details (dict): Authentication details obtained from API key validation
616
+
617
+ Returns:
618
+ EmbeddingsDeleteData: Success response with deletion details
619
+
620
+ Parameters
621
+ ----------
622
+ chunk_ids : typing.Sequence[str]
623
+
624
+ tenant_id : str
625
+
626
+ sub_tenant_id : typing.Optional[str]
627
+
628
+ request_options : typing.Optional[RequestOptions]
629
+ Request-specific configuration.
630
+
631
+ Returns
632
+ -------
633
+ AsyncHttpResponse[EmbeddingsDeleteData]
634
+ Successful Response
635
+ """
636
+ _response = await self._client_wrapper.httpx_client.request(
637
+ "embeddings/delete",
638
+ method="DELETE",
639
+ json={
640
+ "chunk_ids": chunk_ids,
641
+ "tenant_id": tenant_id,
642
+ "sub_tenant_id": sub_tenant_id,
643
+ },
644
+ headers={
645
+ "content-type": "application/json",
646
+ },
647
+ request_options=request_options,
648
+ omit=OMIT,
649
+ )
650
+ try:
651
+ if 200 <= _response.status_code < 300:
652
+ _data = typing.cast(
653
+ EmbeddingsDeleteData,
654
+ parse_obj_as(
655
+ type_=EmbeddingsDeleteData, # type: ignore
656
+ object_=_response.json(),
657
+ ),
658
+ )
659
+ return AsyncHttpResponse(response=_response, data=_data)
660
+ if _response.status_code == 400:
661
+ raise BadRequestError(
662
+ headers=dict(_response.headers),
663
+ body=typing.cast(
664
+ ActualErrorResponse,
665
+ parse_obj_as(
666
+ type_=ActualErrorResponse, # type: ignore
667
+ object_=_response.json(),
668
+ ),
669
+ ),
670
+ )
671
+ if _response.status_code == 401:
672
+ raise UnauthorizedError(
673
+ headers=dict(_response.headers),
674
+ body=typing.cast(
675
+ ActualErrorResponse,
676
+ parse_obj_as(
677
+ type_=ActualErrorResponse, # type: ignore
678
+ object_=_response.json(),
679
+ ),
680
+ ),
681
+ )
682
+ if _response.status_code == 403:
683
+ raise ForbiddenError(
684
+ headers=dict(_response.headers),
685
+ body=typing.cast(
686
+ ActualErrorResponse,
687
+ parse_obj_as(
688
+ type_=ActualErrorResponse, # type: ignore
689
+ object_=_response.json(),
690
+ ),
691
+ ),
692
+ )
693
+ if _response.status_code == 404:
694
+ raise NotFoundError(
695
+ headers=dict(_response.headers),
696
+ body=typing.cast(
697
+ ActualErrorResponse,
698
+ parse_obj_as(
699
+ type_=ActualErrorResponse, # type: ignore
700
+ object_=_response.json(),
701
+ ),
702
+ ),
703
+ )
704
+ if _response.status_code == 422:
705
+ raise UnprocessableEntityError(
706
+ headers=dict(_response.headers),
707
+ body=typing.cast(
708
+ typing.Optional[typing.Any],
709
+ parse_obj_as(
710
+ type_=typing.Optional[typing.Any], # type: ignore
711
+ object_=_response.json(),
712
+ ),
713
+ ),
714
+ )
715
+ if _response.status_code == 500:
716
+ raise InternalServerError(
717
+ headers=dict(_response.headers),
718
+ body=typing.cast(
719
+ ActualErrorResponse,
720
+ parse_obj_as(
721
+ type_=ActualErrorResponse, # type: ignore
722
+ object_=_response.json(),
723
+ ),
724
+ ),
725
+ )
726
+ if _response.status_code == 503:
727
+ raise ServiceUnavailableError(
728
+ headers=dict(_response.headers),
729
+ body=typing.cast(
730
+ ActualErrorResponse,
731
+ parse_obj_as(
732
+ type_=ActualErrorResponse, # type: ignore
733
+ object_=_response.json(),
734
+ ),
735
+ ),
736
+ )
737
+ _response_json = _response.json()
738
+ except JSONDecodeError:
739
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
740
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
741
+
742
+ async def search(
743
+ self,
744
+ *,
745
+ embeddings: typing.Sequence[float],
746
+ tenant_id: str,
747
+ sub_tenant_id: typing.Optional[str] = OMIT,
748
+ max_chunks: typing.Optional[int] = OMIT,
749
+ request_options: typing.Optional[RequestOptions] = None,
750
+ ) -> AsyncHttpResponse[EmbeddingsSearchData]:
751
+ """
752
+ Search for similar embedding chunks using vector similarity.
753
+
754
+ This endpoint performs semantic search by sending an embedding vector to the Findr backend
755
+ and returns a list of the most similar chunk IDs based on vector similarity.
756
+
757
+ Args:
758
+ request (EmbeddingsSearchRequest): The search request containing:
759
+ - embeddings (List[float]): Single embedding vector for similarity search
760
+ - tenant_id (str): Tenant identifier for multi-tenancy
761
+ - sub_tenant_id (str, optional): Sub-tenant identifier, defaults to tenant_id
762
+ - max_chunks (int, optional): Maximum number of chunk IDs to return (default: 10)
763
+ api_details (dict): Authentication details obtained from API key validation
764
+
765
+ Returns:
766
+ EmbeddingsSearchData: List of chunk IDs with similarity scores
767
+
768
+ Parameters
769
+ ----------
770
+ embeddings : typing.Sequence[float]
771
+ Single embedding vector for search
772
+
773
+ tenant_id : str
774
+
775
+ sub_tenant_id : typing.Optional[str]
776
+
777
+ max_chunks : typing.Optional[int]
778
+
779
+ request_options : typing.Optional[RequestOptions]
780
+ Request-specific configuration.
781
+
782
+ Returns
783
+ -------
784
+ AsyncHttpResponse[EmbeddingsSearchData]
785
+ Successful Response
786
+ """
787
+ _response = await self._client_wrapper.httpx_client.request(
788
+ "embeddings/search",
789
+ method="POST",
790
+ json={
791
+ "embeddings": embeddings,
792
+ "tenant_id": tenant_id,
793
+ "sub_tenant_id": sub_tenant_id,
794
+ "max_chunks": max_chunks,
795
+ },
796
+ headers={
797
+ "content-type": "application/json",
798
+ },
799
+ request_options=request_options,
800
+ omit=OMIT,
801
+ )
802
+ try:
803
+ if 200 <= _response.status_code < 300:
804
+ _data = typing.cast(
805
+ EmbeddingsSearchData,
806
+ parse_obj_as(
807
+ type_=EmbeddingsSearchData, # type: ignore
808
+ object_=_response.json(),
809
+ ),
810
+ )
811
+ return AsyncHttpResponse(response=_response, data=_data)
812
+ if _response.status_code == 400:
813
+ raise BadRequestError(
814
+ headers=dict(_response.headers),
815
+ body=typing.cast(
816
+ ActualErrorResponse,
817
+ parse_obj_as(
818
+ type_=ActualErrorResponse, # type: ignore
819
+ object_=_response.json(),
820
+ ),
821
+ ),
822
+ )
823
+ if _response.status_code == 401:
824
+ raise UnauthorizedError(
825
+ headers=dict(_response.headers),
826
+ body=typing.cast(
827
+ ActualErrorResponse,
828
+ parse_obj_as(
829
+ type_=ActualErrorResponse, # type: ignore
830
+ object_=_response.json(),
831
+ ),
832
+ ),
833
+ )
834
+ if _response.status_code == 403:
835
+ raise ForbiddenError(
836
+ headers=dict(_response.headers),
837
+ body=typing.cast(
838
+ ActualErrorResponse,
839
+ parse_obj_as(
840
+ type_=ActualErrorResponse, # type: ignore
841
+ object_=_response.json(),
842
+ ),
843
+ ),
844
+ )
845
+ if _response.status_code == 404:
846
+ raise NotFoundError(
847
+ headers=dict(_response.headers),
848
+ body=typing.cast(
849
+ ActualErrorResponse,
850
+ parse_obj_as(
851
+ type_=ActualErrorResponse, # type: ignore
852
+ object_=_response.json(),
853
+ ),
854
+ ),
855
+ )
856
+ if _response.status_code == 422:
857
+ raise UnprocessableEntityError(
858
+ headers=dict(_response.headers),
859
+ body=typing.cast(
860
+ typing.Optional[typing.Any],
861
+ parse_obj_as(
862
+ type_=typing.Optional[typing.Any], # type: ignore
863
+ object_=_response.json(),
864
+ ),
865
+ ),
866
+ )
867
+ if _response.status_code == 500:
868
+ raise InternalServerError(
869
+ headers=dict(_response.headers),
870
+ body=typing.cast(
871
+ ActualErrorResponse,
872
+ parse_obj_as(
873
+ type_=ActualErrorResponse, # type: ignore
874
+ object_=_response.json(),
875
+ ),
876
+ ),
877
+ )
878
+ if _response.status_code == 503:
879
+ raise ServiceUnavailableError(
880
+ headers=dict(_response.headers),
881
+ body=typing.cast(
882
+ ActualErrorResponse,
883
+ parse_obj_as(
884
+ type_=ActualErrorResponse, # type: ignore
885
+ object_=_response.json(),
886
+ ),
887
+ ),
888
+ )
889
+ _response_json = _response.json()
890
+ except JSONDecodeError:
891
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
892
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
893
+
894
+ async def get_by_chunk_ids(
895
+ self,
896
+ *,
897
+ chunk_ids: typing.Sequence[str],
898
+ tenant_id: str,
899
+ sub_tenant_id: typing.Optional[str] = OMIT,
900
+ request_options: typing.Optional[RequestOptions] = None,
901
+ ) -> AsyncHttpResponse[EmbeddingsGetData]:
902
+ """
903
+ Get embeddings based on chunk IDs.
904
+
905
+ This endpoint returns embeddings for a list of chunk IDs.
906
+
907
+ Returns:
908
+ EmbeddingsGetData: Embeddings data for the requested chunk IDs
909
+
910
+ Parameters
911
+ ----------
912
+ chunk_ids : typing.Sequence[str]
913
+
914
+ tenant_id : str
915
+
916
+ sub_tenant_id : typing.Optional[str]
917
+
918
+ request_options : typing.Optional[RequestOptions]
919
+ Request-specific configuration.
920
+
921
+ Returns
922
+ -------
923
+ AsyncHttpResponse[EmbeddingsGetData]
924
+ Successful Response
925
+ """
926
+ _response = await self._client_wrapper.httpx_client.request(
927
+ "embeddings/by-chunk-ids",
928
+ method="POST",
929
+ json={
930
+ "chunk_ids": chunk_ids,
931
+ "tenant_id": tenant_id,
932
+ "sub_tenant_id": sub_tenant_id,
933
+ },
934
+ headers={
935
+ "content-type": "application/json",
936
+ },
937
+ request_options=request_options,
938
+ omit=OMIT,
939
+ )
940
+ try:
941
+ if 200 <= _response.status_code < 300:
942
+ _data = typing.cast(
943
+ EmbeddingsGetData,
944
+ parse_obj_as(
945
+ type_=EmbeddingsGetData, # type: ignore
946
+ object_=_response.json(),
947
+ ),
948
+ )
949
+ return AsyncHttpResponse(response=_response, data=_data)
950
+ if _response.status_code == 400:
951
+ raise BadRequestError(
952
+ headers=dict(_response.headers),
953
+ body=typing.cast(
954
+ ActualErrorResponse,
955
+ parse_obj_as(
956
+ type_=ActualErrorResponse, # type: ignore
957
+ object_=_response.json(),
958
+ ),
959
+ ),
960
+ )
961
+ if _response.status_code == 401:
962
+ raise UnauthorizedError(
963
+ headers=dict(_response.headers),
964
+ body=typing.cast(
965
+ ActualErrorResponse,
966
+ parse_obj_as(
967
+ type_=ActualErrorResponse, # type: ignore
968
+ object_=_response.json(),
969
+ ),
970
+ ),
971
+ )
972
+ if _response.status_code == 403:
973
+ raise ForbiddenError(
974
+ headers=dict(_response.headers),
975
+ body=typing.cast(
976
+ ActualErrorResponse,
977
+ parse_obj_as(
978
+ type_=ActualErrorResponse, # type: ignore
979
+ object_=_response.json(),
980
+ ),
981
+ ),
982
+ )
983
+ if _response.status_code == 404:
984
+ raise NotFoundError(
985
+ headers=dict(_response.headers),
986
+ body=typing.cast(
987
+ ActualErrorResponse,
988
+ parse_obj_as(
989
+ type_=ActualErrorResponse, # type: ignore
990
+ object_=_response.json(),
991
+ ),
992
+ ),
993
+ )
994
+ if _response.status_code == 422:
995
+ raise UnprocessableEntityError(
996
+ headers=dict(_response.headers),
997
+ body=typing.cast(
998
+ typing.Optional[typing.Any],
999
+ parse_obj_as(
1000
+ type_=typing.Optional[typing.Any], # type: ignore
1001
+ object_=_response.json(),
1002
+ ),
1003
+ ),
1004
+ )
1005
+ if _response.status_code == 500:
1006
+ raise InternalServerError(
1007
+ headers=dict(_response.headers),
1008
+ body=typing.cast(
1009
+ ActualErrorResponse,
1010
+ parse_obj_as(
1011
+ type_=ActualErrorResponse, # type: ignore
1012
+ object_=_response.json(),
1013
+ ),
1014
+ ),
1015
+ )
1016
+ if _response.status_code == 503:
1017
+ raise ServiceUnavailableError(
1018
+ headers=dict(_response.headers),
1019
+ body=typing.cast(
1020
+ ActualErrorResponse,
1021
+ parse_obj_as(
1022
+ type_=ActualErrorResponse, # type: ignore
1023
+ object_=_response.json(),
1024
+ ),
1025
+ ),
1026
+ )
1027
+ _response_json = _response.json()
1028
+ except JSONDecodeError:
1029
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
1030
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
1031
+
1032
+ async def create_collection(
1033
+ self, *, tenant_id: str, request_options: typing.Optional[RequestOptions] = None
1034
+ ) -> AsyncHttpResponse[EmbeddingsCreateCollectionData]:
1035
+ """
1036
+ Create an embeddings collection for the given tenant in Findr.
1037
+
1038
+ sub_tenant_id is set to be the same as tenant_id as per requirements.
1039
+
1040
+ Returns:
1041
+ EmbeddingsCreateCollectionData: Success response with collection details
1042
+
1043
+ Parameters
1044
+ ----------
1045
+ tenant_id : str
1046
+
1047
+ request_options : typing.Optional[RequestOptions]
1048
+ Request-specific configuration.
1049
+
1050
+ Returns
1051
+ -------
1052
+ AsyncHttpResponse[EmbeddingsCreateCollectionData]
1053
+ Successful Response
1054
+ """
1055
+ _response = await self._client_wrapper.httpx_client.request(
1056
+ "embeddings/create_embeddings_tenant",
1057
+ method="POST",
1058
+ params={
1059
+ "tenant_id": tenant_id,
1060
+ },
1061
+ request_options=request_options,
1062
+ )
1063
+ try:
1064
+ if 200 <= _response.status_code < 300:
1065
+ _data = typing.cast(
1066
+ EmbeddingsCreateCollectionData,
1067
+ parse_obj_as(
1068
+ type_=EmbeddingsCreateCollectionData, # type: ignore
1069
+ object_=_response.json(),
1070
+ ),
1071
+ )
1072
+ return AsyncHttpResponse(response=_response, data=_data)
1073
+ if _response.status_code == 400:
1074
+ raise BadRequestError(
1075
+ headers=dict(_response.headers),
1076
+ body=typing.cast(
1077
+ ActualErrorResponse,
1078
+ parse_obj_as(
1079
+ type_=ActualErrorResponse, # type: ignore
1080
+ object_=_response.json(),
1081
+ ),
1082
+ ),
1083
+ )
1084
+ if _response.status_code == 401:
1085
+ raise UnauthorizedError(
1086
+ headers=dict(_response.headers),
1087
+ body=typing.cast(
1088
+ ActualErrorResponse,
1089
+ parse_obj_as(
1090
+ type_=ActualErrorResponse, # type: ignore
1091
+ object_=_response.json(),
1092
+ ),
1093
+ ),
1094
+ )
1095
+ if _response.status_code == 403:
1096
+ raise ForbiddenError(
1097
+ headers=dict(_response.headers),
1098
+ body=typing.cast(
1099
+ ActualErrorResponse,
1100
+ parse_obj_as(
1101
+ type_=ActualErrorResponse, # type: ignore
1102
+ object_=_response.json(),
1103
+ ),
1104
+ ),
1105
+ )
1106
+ if _response.status_code == 404:
1107
+ raise NotFoundError(
1108
+ headers=dict(_response.headers),
1109
+ body=typing.cast(
1110
+ ActualErrorResponse,
1111
+ parse_obj_as(
1112
+ type_=ActualErrorResponse, # type: ignore
1113
+ object_=_response.json(),
1114
+ ),
1115
+ ),
1116
+ )
1117
+ if _response.status_code == 422:
1118
+ raise UnprocessableEntityError(
1119
+ headers=dict(_response.headers),
1120
+ body=typing.cast(
1121
+ typing.Optional[typing.Any],
1122
+ parse_obj_as(
1123
+ type_=typing.Optional[typing.Any], # type: ignore
1124
+ object_=_response.json(),
1125
+ ),
1126
+ ),
1127
+ )
1128
+ if _response.status_code == 500:
1129
+ raise InternalServerError(
1130
+ headers=dict(_response.headers),
1131
+ body=typing.cast(
1132
+ ActualErrorResponse,
1133
+ parse_obj_as(
1134
+ type_=ActualErrorResponse, # type: ignore
1135
+ object_=_response.json(),
1136
+ ),
1137
+ ),
1138
+ )
1139
+ if _response.status_code == 503:
1140
+ raise ServiceUnavailableError(
1141
+ headers=dict(_response.headers),
1142
+ body=typing.cast(
1143
+ ActualErrorResponse,
1144
+ parse_obj_as(
1145
+ type_=ActualErrorResponse, # type: ignore
1146
+ object_=_response.json(),
1147
+ ),
1148
+ ),
1149
+ )
1150
+ _response_json = _response.json()
1151
+ except JSONDecodeError:
1152
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
1153
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)