11import warnings
22from time import sleep
3- from typing import TypeVar
43
54import httpx
65
1110from mindee .logger import logger
1211from mindee .mindee_http .cancellation_token import CancellationToken
1312from mindee .parsing .common .common_response import CommonStatus
13+ from mindee .v2 .client_options .base_annotation_parameters import BaseAnnotationParameters
1414from mindee .v2 .client_options .base_product_parameters import BaseProductParameters
15+ from mindee .v2 .client_options .base_rag_document_upload_parameters import (
16+ BaseRagDocumentUploadParameters ,
17+ )
1518from mindee .v2 .client_options .base_search_parameters import (
1619 BaseSearchParameters ,
1720 TypeSearchResponse ,
1821)
1922from mindee .v2 .mindee_http .mindee_api_v2 import MindeeAPIV2
20- from mindee .v2 .parsing .inference .base_inference_response import BaseInferenceResponse
23+ from mindee .v2 .parsing .base_rag_annotation_response import (
24+ TypeRagAnnotationResponse ,
25+ )
26+ from mindee .v2 .parsing .inference .base_inference_response import (
27+ TypeBaseInferenceResponse ,
28+ )
2129from mindee .v2 .parsing .job .job_response import JobResponse
2230from mindee .v2 .parsing .search .search_response import SearchResponse
2331
24- TypeBaseInferenceResponse = TypeVar (
25- "TypeBaseInferenceResponse" , bound = BaseInferenceResponse
26- )
27-
2832
2933class Client :
3034 """
@@ -169,6 +173,143 @@ def enqueue_and_get_result(
169173
170174 raise MindeeError (f"Couldn't retrieve document after { try_counter + 1 } tries." )
171175
176+ def upload_rag_document (
177+ self ,
178+ input_source : LocalInputSource ,
179+ parameters : BaseRagDocumentUploadParameters [TypeRagAnnotationResponse ],
180+ ) -> TypeRagAnnotationResponse :
181+ """
182+ Not recommended for general use, prefer ``upload_and_get_rag_document``.
183+ You will need to poll until the document is ready for use.
184+ Add a document to the RAG database.
185+ """
186+ return self .mindee_api .req_post_rag_document (input_source , parameters )
187+
188+ def upload_and_get_rag_document (
189+ self ,
190+ input_source : LocalInputSource ,
191+ parameters : BaseRagDocumentUploadParameters [TypeRagAnnotationResponse ],
192+ polling_options : PollingOptions | None = None ,
193+ cancellation_token : CancellationToken | None = None ,
194+ ) -> TypeRagAnnotationResponse :
195+ """
196+ Add a document to the RAG database and return the initial annotation.
197+ """
198+ initial_response = self .upload_rag_document (input_source , parameters )
199+ if initial_response .status != "Processing" :
200+ return initial_response
201+ if polling_options is None :
202+ polling_options = PollingOptions ()
203+ return self ._poll_for_rag_document (
204+ initial_response , polling_options , cancellation_token
205+ )
206+
207+ def get_rag_document (
208+ self , response_type : type [TypeRagAnnotationResponse ], document_id : str
209+ ) -> TypeRagAnnotationResponse :
210+ """
211+ Not recommended for general use, prefer ``get_ready_rag_document``.
212+ You will need to poll until the document is ready for use.
213+ Get a document's info and annotations from the RAG database.
214+ """
215+ return self .mindee_api .req_get_rag_annotation (response_type , document_id )
216+
217+ def get_ready_rag_document (
218+ self ,
219+ response_type : type [TypeRagAnnotationResponse ],
220+ document_id : str ,
221+ polling_options : PollingOptions | None = None ,
222+ cancellation_token : CancellationToken | None = None ,
223+ ):
224+ """
225+ Get a document's info and annotations from the RAG database.
226+ """
227+ initial_response = self .get_rag_document (response_type , document_id )
228+ if initial_response .status != "Processing" :
229+ return initial_response
230+ if polling_options is None :
231+ polling_options = PollingOptions ()
232+ return self ._poll_for_rag_document (
233+ initial_response , polling_options , cancellation_token
234+ )
235+
236+ def update_rag_annotations (
237+ self , parameters : BaseAnnotationParameters [TypeRagAnnotationResponse ]
238+ ) -> TypeRagAnnotationResponse :
239+ """
240+ Not recommended for general use, prefer ``update_and_get_rag_annotations``.
241+ You will need to poll until the document is ready for use.
242+ Update a document's annotations in the RAG database.
243+ """
244+ return self .mindee_api .req_patch_rag_annotation (parameters )
245+
246+ def update_and_get_rag_annotations (
247+ self ,
248+ parameters : BaseAnnotationParameters [TypeRagAnnotationResponse ],
249+ polling_options : PollingOptions | None = None ,
250+ cancellation_token : CancellationToken | None = None ,
251+ ) -> TypeRagAnnotationResponse :
252+ """
253+ Update a document's annotations in the RAG database.
254+ """
255+ initial_response = self .update_rag_annotations (parameters )
256+ if initial_response .status != "Processing" :
257+ return initial_response
258+ if polling_options is None :
259+ polling_options = PollingOptions ()
260+ return self ._poll_for_rag_document (
261+ initial_response , polling_options , cancellation_token
262+ )
263+
264+ def delete_extraction_rag_document (self , document_id : str ) -> bool :
265+ """
266+ Delete a document from the RAG database.
267+ For extraction models only.
268+ """
269+ return self .mindee_api .req_delete_extraction_rag_document (document_id )
270+
271+ def _poll_for_rag_document (
272+ self ,
273+ initial_response : TypeRagAnnotationResponse ,
274+ polling_options : PollingOptions ,
275+ cancellation_token : CancellationToken | None = None ,
276+ ) -> TypeRagAnnotationResponse :
277+ """
278+ Poll until the document is finished processing or the max number of attempts is reached.
279+ """
280+ logger .info ("Polling for RAG document ID: %s" , initial_response .id )
281+ polling_options .validate_settings ()
282+ max_retries = polling_options .max_retries + 1
283+
284+ logger .debug (
285+ "Waiting %s seconds before attempting to retrieve the result..." ,
286+ polling_options .initial_delay_sec ,
287+ )
288+
289+ if cancellation_token and cancellation_token .is_canceled :
290+ raise MindeeError ("Request canceled through cancellation token." )
291+
292+ sleep (polling_options .initial_delay_sec )
293+ document_id = initial_response .id
294+ retry_count = 1
295+
296+ while retry_count < max_retries :
297+ if cancellation_token and cancellation_token .is_canceled :
298+ raise MindeeError ("Request canceled through cancellation token." )
299+ logger .info ("Poll attempt %s of %s" , retry_count , max_retries )
300+
301+ response = self .get_rag_document (type (initial_response ), document_id )
302+ retry_count += 1
303+
304+ if response .status == "Processing" :
305+ sleep (polling_options .delay_sec )
306+ continue
307+ if response .status == "Failed" :
308+ raise MindeeError ("Job failed without an error payload." )
309+ return response
310+
311+ raise MindeeError (f"RAG polling not complete after { retry_count - 1 } attempts." )
312+
172313 def search (
173314 self , params : BaseSearchParameters [TypeSearchResponse ]
174315 ) -> TypeSearchResponse :
@@ -183,7 +324,7 @@ def search_models(
183324 self , name : str | None = None , model_type : str | None = None
184325 ) -> SearchResponse :
185326 """
186- Deprecated. Use `search` instead.
327+ Deprecated: use `search` instead.
187328 """
188329 warnings .warn (
189330 "search_models is deprecated, use search instead." ,
0 commit comments