Skip to content

Commit 737505c

Browse files
committed
add client methods
1 parent bf88d99 commit 737505c

17 files changed

Lines changed: 481 additions & 72 deletions

‎src/main/java/com/mindee/v2/MindeeClient.java‎

Lines changed: 227 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,15 @@
33
import com.mindee.MindeeException;
44
import com.mindee.input.LocalInputSource;
55
import com.mindee.input.URLInputSource;
6+
import com.mindee.v2.clientoptions.BaseAnnotationParameters;
67
import com.mindee.v2.clientoptions.BaseProductParameters;
8+
import com.mindee.v2.clientoptions.BaseRagDocumentUploadParameters;
79
import com.mindee.v2.clientoptions.BaseSearchParameters;
810
import com.mindee.v2.clientoptions.PollingOptions;
911
import com.mindee.v2.http.MindeeApiV2;
1012
import com.mindee.v2.http.MindeeHttpApiV2;
1113
import com.mindee.v2.http.MindeeHttpExceptionV2;
14+
import com.mindee.v2.parsing.BaseRagAnnotationResponse;
1215
import com.mindee.v2.parsing.BaseResponse;
1316
import com.mindee.v2.parsing.JobResponse;
1417
import com.mindee.v2.parsing.error.ErrorResponse;
@@ -277,6 +280,230 @@ public SearchResponse searchModels(String modelName, String modelType) {
277280
.reqGetSearch(ModelSearchParameters.builder().name(modelName).modelType(modelType).build());
278281
}
279282

283+
/**
284+
* Not recommended for general use, prefer {@link #uploadAndGetRagDocument}.
285+
* You will need to poll until the document is ready for use.
286+
* Add a document to the RAG database.
287+
*
288+
* @param inputSource The file to upload.
289+
* @param parameters RAG document upload parameters.
290+
* @return an instance of {@link BaseRagAnnotationResponse}.
291+
*/
292+
public <TAnnotationResponse extends BaseRagAnnotationResponse> TAnnotationResponse uploadRagDocument(
293+
LocalInputSource inputSource,
294+
BaseRagDocumentUploadParameters<TAnnotationResponse> parameters
295+
) throws IOException {
296+
logger.log(System.Logger.Level.INFO, "Adding a document to the RAG database");
297+
return mindeeApi.reqPostRagDocument(parameters, inputSource);
298+
}
299+
300+
/**
301+
* Add a document to the RAG database, poll, and return the initial annotation.
302+
*
303+
* @param inputSource The file to upload.
304+
* @param parameters RAG document upload parameters.
305+
* @return an instance of {@link BaseRagAnnotationResponse}.
306+
*/
307+
public <TAnnotationResponse extends BaseRagAnnotationResponse> TAnnotationResponse uploadAndGetRagDocument(
308+
LocalInputSource inputSource,
309+
BaseRagDocumentUploadParameters<TAnnotationResponse> parameters
310+
) throws IOException, InterruptedException {
311+
return uploadAndGetRagDocument(inputSource, parameters, null);
312+
}
313+
314+
/**
315+
* Add a document to the RAG database, poll, and return the initial annotation.
316+
*
317+
* @param inputSource The file to upload.
318+
* @param parameters RAG document upload parameters.
319+
* @param pollingOptions Polling options (if null, default options are used).
320+
* @return an instance of {@link BaseRagAnnotationResponse}.
321+
*/
322+
public <TAnnotationResponse extends BaseRagAnnotationResponse> TAnnotationResponse uploadAndGetRagDocument(
323+
LocalInputSource inputSource,
324+
BaseRagDocumentUploadParameters<TAnnotationResponse> parameters,
325+
PollingOptions pollingOptions
326+
) throws IOException, InterruptedException {
327+
if (pollingOptions == null) {
328+
pollingOptions = PollingOptions.builder().build();
329+
}
330+
TAnnotationResponse initialResponse = uploadRagDocument(inputSource, parameters);
331+
if (!"Processing".equals(initialResponse.getStatus())) {
332+
return initialResponse;
333+
}
334+
return pollForRagDocument(parameters.getResponseClass(), initialResponse, pollingOptions);
335+
}
336+
337+
/**
338+
* Not recommended for general use, prefer {@link #getReadyRagDocument}.
339+
* You will need to poll until the document is ready for use.
340+
* Get a document's info and annotations from the RAG database.
341+
*
342+
* @param responseClass The class of the response.
343+
* @param documentId The document's ID.
344+
* @return an instance of {@link BaseRagAnnotationResponse}.
345+
*/
346+
public <TAnnotationResponse extends BaseRagAnnotationResponse> TAnnotationResponse getRagDocument(
347+
Class<TAnnotationResponse> responseClass,
348+
String documentId
349+
) {
350+
logger.log(System.Logger.Level.INFO, "Getting RAG document ID: {0}", documentId);
351+
return mindeeApi.reqGetRagAnnotation(responseClass, documentId);
352+
}
353+
354+
/**
355+
* Get a document's info and annotations from the RAG database, polling if it is still processing.
356+
*
357+
* @param responseClass The class of the response.
358+
* @param documentId The document's ID.
359+
* @return an instance of {@link BaseRagAnnotationResponse}.
360+
*/
361+
public <TAnnotationResponse extends BaseRagAnnotationResponse> TAnnotationResponse getReadyRagDocument(
362+
Class<TAnnotationResponse> responseClass,
363+
String documentId
364+
) throws InterruptedException {
365+
return getReadyRagDocument(responseClass, documentId, null);
366+
}
367+
368+
/**
369+
* Get a document's info and annotations from the RAG database, polling if it is still processing.
370+
*
371+
* @param responseClass The class of the response.
372+
* @param documentId The document's ID.
373+
* @param pollingOptions Polling options (if null, default options are used).
374+
* @return an instance of {@link BaseRagAnnotationResponse}.
375+
*/
376+
public <TAnnotationResponse extends BaseRagAnnotationResponse> TAnnotationResponse getReadyRagDocument(
377+
Class<TAnnotationResponse> responseClass,
378+
String documentId,
379+
PollingOptions pollingOptions
380+
) throws InterruptedException {
381+
TAnnotationResponse initialResponse = getRagDocument(responseClass, documentId);
382+
if (!"Processing".equals(initialResponse.getStatus())) {
383+
return initialResponse;
384+
}
385+
386+
if (pollingOptions == null) {
387+
pollingOptions = PollingOptions.builder().build();
388+
}
389+
return pollForRagDocument(responseClass, initialResponse, pollingOptions);
390+
}
391+
392+
/**
393+
* Not recommended for general use, prefer {@link #updateAndGetRagAnnotation}.
394+
* You will need to poll until the document is ready for use.
395+
* Update a document's annotations in the RAG database.
396+
*
397+
* @param parameters Annotation parameters.
398+
* @return an instance of {@link BaseRagAnnotationResponse}.
399+
*/
400+
public <TAnnotationResponse extends BaseRagAnnotationResponse> TAnnotationResponse updateRagAnnotation(
401+
BaseAnnotationParameters<TAnnotationResponse> parameters
402+
) {
403+
logger
404+
.log(System.Logger.Level.INFO, "Updating RAG document ID: {0}", parameters.getDocumentId());
405+
return mindeeApi.reqPatchRagAnnotation(parameters);
406+
}
407+
408+
/**
409+
* Update a document's annotations in the RAG database and poll until complete.
410+
*
411+
* @param parameters Annotation parameters.
412+
* @return an instance of {@link BaseRagAnnotationResponse}.
413+
*/
414+
public <TAnnotationResponse extends BaseRagAnnotationResponse> TAnnotationResponse updateAndGetRagAnnotation(
415+
BaseAnnotationParameters<TAnnotationResponse> parameters
416+
) throws InterruptedException {
417+
return updateAndGetRagAnnotation(parameters, null);
418+
}
419+
420+
/**
421+
* Update a document's annotations in the RAG database and poll until complete.
422+
*
423+
* @param parameters Annotation parameters.
424+
* @param pollingOptions Polling options (if null, default options are used).
425+
* @return an instance of {@link BaseRagAnnotationResponse}.
426+
*/
427+
public <TAnnotationResponse extends BaseRagAnnotationResponse> TAnnotationResponse updateAndGetRagAnnotation(
428+
BaseAnnotationParameters<TAnnotationResponse> parameters,
429+
PollingOptions pollingOptions
430+
) throws InterruptedException {
431+
TAnnotationResponse initialResponse = updateRagAnnotation(parameters);
432+
if (!"Processing".equals(initialResponse.getStatus())) {
433+
return initialResponse;
434+
}
435+
436+
if (pollingOptions == null) {
437+
pollingOptions = PollingOptions.builder().build();
438+
}
439+
return pollForRagDocument(parameters.getResponseClass(), initialResponse, pollingOptions);
440+
}
441+
442+
/**
443+
* Delete a document from the RAG database.
444+
* For extraction models only.
445+
*
446+
* @param documentId The document's ID.
447+
* @return true if successful.
448+
*/
449+
public boolean deleteExtractionRagDocument(String documentId) {
450+
logger.log(System.Logger.Level.INFO, "Deleting RAG document ID: {0}", documentId);
451+
return mindeeApi.reqDeleteExtractionRagDocument(documentId);
452+
}
453+
454+
/**
455+
* Poll until the RAG document is finished processing or the max number of attempts is reached.
456+
*
457+
* @param responseClass The class of the response.
458+
* @param initialResponse The initial annotation response.
459+
* @param pollingOptions Polling options.
460+
* @return an instance of {@link BaseRagAnnotationResponse}.
461+
* @throws InterruptedException Throws if the thread is interrupted.
462+
*/
463+
private <TAnnotationResponse extends BaseRagAnnotationResponse> TAnnotationResponse pollForRagDocument(
464+
Class<TAnnotationResponse> responseClass,
465+
BaseRagAnnotationResponse initialResponse,
466+
PollingOptions pollingOptions
467+
) throws InterruptedException {
468+
logger
469+
.log(System.Logger.Level.INFO, "Polling for RAG document ID: {0}", initialResponse.getId());
470+
int maxRetries = pollingOptions.getMaxRetries() + 1;
471+
472+
logger
473+
.log(
474+
System.Logger.Level.DEBUG,
475+
"Waiting {0} seconds before attempting to retrieve the result...",
476+
pollingOptions.getInitialDelaySec()
477+
);
478+
479+
interruptibleSleep(
480+
(long) (pollingOptions.getInitialDelaySec() * 1000),
481+
pollingOptions.getCancelToken()
482+
);
483+
484+
String documentId = initialResponse.getId();
485+
long intervalMillis = (long) (pollingOptions.getIntervalSec() * 1000);
486+
int retryCount = 1;
487+
488+
while (retryCount < maxRetries) {
489+
interruptibleSleep(intervalMillis, pollingOptions.getCancelToken());
490+
logger.log(System.Logger.Level.DEBUG, "Poll attempt {0} of {1}", retryCount, maxRetries);
491+
492+
TAnnotationResponse response = getRagDocument(responseClass, documentId);
493+
retryCount++;
494+
495+
String status = response.getStatus();
496+
if ("Processing".equals(status)) {
497+
continue;
498+
} else if ("Failed".equals(status)) {
499+
throw new MindeeException("RAG failed without an error payload.");
500+
} else {
501+
return response;
502+
}
503+
}
504+
throw new MindeeException("RAG polling not complete after " + retryCount + " attempts.");
505+
}
506+
280507
/**
281508
* Common logic for polling an asynchronous job for local & url files.
282509
*

‎src/main/java/com/mindee/v2/clientoptions/BaseAnnotationParameters.java‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ protected BaseAnnotationParameters(Class<TAnnotationResponse> responseClass, Str
3636
/**
3737
* Gets the request parameters for the upload request.
3838
*/
39-
public abstract Map<String, String> getRequestParameters();
39+
public abstract Map<String, Object> getRequestParameters();
4040

4141
protected abstract static class BaseBuilder<T extends BaseBuilder<T>> {
4242
protected String documentId;

‎src/main/java/com/mindee/v2/clientoptions/BaseProductParameters.java‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ public abstract class BaseProductParameters {
2828

2929
/**
3030
* Base constructor.
31-
*
31+
*
3232
* @param modelId {@link #modelId}
3333
* @param alias {@link #alias}
3434
* @param webhookIds {@link #webhookIds}

‎src/main/java/com/mindee/v2/http/MindeeHttpApiV2.java‎

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,6 @@ public <TAnnotationResponse extends BaseRagAnnotationResponse> TAnnotationRespon
181181
}
182182

183183
@Override
184-
@SuppressWarnings("unchecked")
185184
public <TAnnotationResponse extends BaseRagAnnotationResponse> TAnnotationResponse reqGetRagAnnotation(
186185
Class<TAnnotationResponse> responseClass,
187186
String documentId
@@ -197,7 +196,7 @@ public <TAnnotationResponse extends BaseRagAnnotationResponse> TAnnotationRespon
197196
var get = new HttpGet(url);
198197

199198
logger.log(System.Logger.Level.DEBUG, "HTTP GET to {0} ...", url);
200-
return (TAnnotationResponse) executeAPIRequest(get, BaseRagAnnotationResponse.class);
199+
return executeAPIRequest(get, responseClass);
201200
}
202201

203202
@Override

‎src/main/java/com/mindee/v2/product/extraction/ragdocuments/AnnotatedBaseField.java‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,5 +27,4 @@ public class AnnotatedBaseField {
2727
*/
2828
@JsonProperty("guidelines")
2929
private String guidelines;
30-
3130
}
Lines changed: 48 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.mindee.v2.product.extraction.ragdocuments;
22

33
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
4+
import com.fasterxml.jackson.annotation.JsonValue;
45
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
56
import com.mindee.v2.parsing.inference.field.FieldType;
67
import lombok.AllArgsConstructor;
@@ -9,48 +10,74 @@
910
import lombok.NoArgsConstructor;
1011

1112
/**
12-
* Return the field class dynamically. //[cite: 6]
13+
* Return the field class dynamically.
1314
*/
1415
@Getter
1516
@EqualsAndHashCode
1617
@JsonIgnoreProperties(ignoreUnknown = true)
1718
@AllArgsConstructor
1819
@NoArgsConstructor
19-
@JsonDeserialize(using = DynamicAnnotationFieldDeserializer.class) // [cite: 6]
20+
@JsonDeserialize(using = DynamicAnnotationFieldDeserializer.class)
2021
public class AnnotatedDynamicField {
2122

2223
/**
23-
* Value as a simple field. //[cite: 6]
24+
* Value as a simple field.
2425
*/
25-
private AnnotatedSimpleField simpleField; // [cite: 6]
26+
private AnnotatedSimpleField simpleField;
2627

2728
/**
28-
* Value as an object field. //[cite: 6]
29+
* Value as an object field.
2930
*/
30-
private AnnotatedObjectField objectField; // [cite: 6]
31+
private AnnotatedObjectField objectField;
3132

3233
/**
33-
* Value as a list field. //[cite: 6]
34+
* Value as a list field.
3435
*/
35-
private AnnotatedListField listField; // [cite: 6]
36+
private AnnotatedListField listField;
3637

3738
/**
38-
* The type of field. //[cite: 6]
39+
* The type of field.
3940
*/
40-
private FieldType type; // [cite: 6]
41+
private FieldType type;
4142

4243
/**
43-
* Default constructor. //[cite: 6]
44+
* Constructor for a simple field.
4445
*/
45-
public AnnotatedDynamicField(
46-
FieldType type,
47-
AnnotatedSimpleField simpleField,
48-
AnnotatedObjectField objectField,
49-
AnnotatedListField listField
50-
) {
51-
this.type = type; // [cite: 6]
52-
this.simpleField = simpleField; // [cite: 6]
53-
this.objectField = objectField; // [cite: 6]
54-
this.listField = listField; // [cite: 6]
46+
public AnnotatedDynamicField(AnnotatedSimpleField field) {
47+
this.type = FieldType.SIMPLE_FIELD;
48+
this.simpleField = field;
49+
this.objectField = null;
50+
this.listField = null;
51+
}
52+
53+
/**
54+
* Constructor for a list field.
55+
*/
56+
public AnnotatedDynamicField(AnnotatedListField field) {
57+
this.type = FieldType.LIST_FIELD;
58+
this.simpleField = null;
59+
this.objectField = null;
60+
this.listField = field;
61+
}
62+
63+
/**
64+
* Constructor for an object field.
65+
*/
66+
public AnnotatedDynamicField(AnnotatedObjectField field) {
67+
this.type = FieldType.OBJECT_FIELD;
68+
this.simpleField = null;
69+
this.objectField = field;
70+
this.listField = null;
71+
}
72+
73+
@JsonValue
74+
public AnnotatedBaseField getField() {
75+
if (simpleField != null) {
76+
return simpleField;
77+
}
78+
if (listField != null) {
79+
return listField;
80+
}
81+
return objectField;
5582
}
5683
}

0 commit comments

Comments
 (0)