Skip to content

Commit 5e93607

Browse files
committed
use annotation for product slugs
1 parent c7c941c commit 5e93607

13 files changed

Lines changed: 123 additions & 53 deletions

File tree

.github/workflows/_test-integrations.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ jobs:
3535
MINDEE_API_KEY: ${{ secrets.MINDEE_API_KEY_SE_TESTS }}
3636
WORKFLOW_ID: ${{ secrets.WORKFLOW_ID_SE_TESTS }}
3737
MINDEE_V2_API_KEY: ${{ secrets.MINDEE_V2_SE_TESTS_API_KEY }}
38-
MINDEE_V2_FINDOC_MODEL_ID: ${{ secrets.MINDEE_V2_SE_TESTS_FINDOC_MODEL_ID }}
38+
MINDEE_V2_SE_TESTS_FINDOC_MODEL_ID: ${{ secrets.MINDEE_V2_SE_TESTS_FINDOC_MODEL_ID }}
3939
MINDEE_V2_SE_TESTS_BLANK_PDF_URL: ${{ secrets.MINDEE_V2_SE_TESTS_BLANK_PDF_URL }}
4040
run: |
4141
mvn clean test-compile failsafe:integration-test failsafe:verify

src/main/java/com/mindee/InferenceParameters.java

Lines changed: 6 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package com.mindee;
22

33
import com.mindee.v2.clientOptions.BaseParameters;
4-
import java.util.Objects;
4+
import com.mindee.v2.http.ProductInfo;
55
import lombok.EqualsAndHashCode;
66
import lombok.Getter;
77
import org.apache.hc.client5.http.entity.mime.MultipartEntityBuilder;
@@ -11,6 +11,7 @@
1111
*/
1212
@Getter
1313
@EqualsAndHashCode(callSuper = true)
14+
@ProductInfo(slug = "extraction")
1415
public final class InferenceParameters extends BaseParameters {
1516
/**
1617
* Enhance extraction accuracy with Retrieval-Augmented Generation.
@@ -51,7 +52,7 @@ private InferenceParameters(
5152
String textContext,
5253
String dataSchema
5354
) {
54-
super(modelId, alias, webhookIds, pollingOptions, "extraction");
55+
super(modelId, alias, webhookIds, pollingOptions);
5556
this.rag = rag;
5657
this.rawText = rawText;
5758
this.polygon = polygon;
@@ -96,21 +97,16 @@ public static Builder builder(String modelId) {
9697
/**
9798
* Fluent builder for {@link InferenceParameters}.
9899
*/
99-
public static final class Builder {
100-
101-
private final String modelId;
100+
public static final class Builder extends BaseParameters.BaseBuilder<Builder> {
102101
private Boolean rag = null;
103102
private Boolean rawText = null;
104103
private Boolean polygon = null;
105104
private Boolean confidence = null;
106-
private String alias;
107-
private String[] webhookIds = new String[] {};
108105
private String textContext;
109106
private String dataSchema;
110-
private AsyncPollingOptions pollingOptions = AsyncPollingOptions.builder().build();
111107

112-
private Builder(String modelId) {
113-
this.modelId = Objects.requireNonNull(modelId, "modelId must not be null");
108+
Builder(String modelId) {
109+
super(modelId);
114110
}
115111

116112
/** Enhance extraction accuracy with Retrieval-Augmented Generation. */
@@ -140,18 +136,6 @@ public Builder confidence(Boolean confidence) {
140136
return this;
141137
}
142138

143-
/** Set an alias for the uploaded document. */
144-
public Builder alias(String alias) {
145-
this.alias = alias;
146-
return this;
147-
}
148-
149-
/** Provide IDs of webhooks to forward the API response to. */
150-
public Builder webhookIds(String[] webhookIds) {
151-
this.webhookIds = webhookIds;
152-
return this;
153-
}
154-
155139
/** Provide additional text context used by the model during inference. */
156140
public Builder textContext(String textContext) {
157141
this.textContext = textContext;
@@ -164,12 +148,6 @@ public Builder dataSchema(String dataSchema) {
164148
return this;
165149
}
166150

167-
/** Set polling options. */
168-
public Builder pollingOptions(AsyncPollingOptions pollingOptions) {
169-
this.pollingOptions = pollingOptions;
170-
return this;
171-
}
172-
173151
/** Build an immutable {@link InferenceParameters} instance. */
174152
public InferenceParameters build() {
175153
return new InferenceParameters(

src/main/java/com/mindee/MindeeClientV2.java

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ public <TResponse extends CommonResponse> TResponse enqueueAndGetResult(
142142
LocalInputSource inputSource,
143143
BaseParameters params
144144
) throws IOException, InterruptedException {
145-
validatePollingOptions(params.getPollingOptions());
145+
params.validatePollingOptions();
146146
JobResponse job = enqueue(inputSource, params);
147147
return pollAndFetch(responseClass, job, params);
148148
}
@@ -161,7 +161,7 @@ public <TResponse extends CommonResponse> TResponse enqueueAndGetResult(
161161
URLInputSource inputSource,
162162
BaseParameters params
163163
) throws IOException, InterruptedException {
164-
validatePollingOptions(params.getPollingOptions());
164+
params.validatePollingOptions();
165165
JobResponse job = enqueue(inputSource, params);
166166
return pollAndFetch(responseClass, job, params);
167167
}
@@ -210,16 +210,4 @@ private static MindeeApiV2 createDefaultApiV2(String apiKey) {
210210
: new MindeeSettingsV2(apiKey);
211211
return MindeeHttpApiV2.builder().mindeeSettings(settings).build();
212212
}
213-
214-
private static void validatePollingOptions(AsyncPollingOptions p) {
215-
if (p.getInitialDelaySec() < 1) {
216-
throw new IllegalArgumentException("Initial delay must be ≥ 1 s");
217-
}
218-
if (p.getIntervalSec() < 1) {
219-
throw new IllegalArgumentException("Interval must be ≥ 1 s");
220-
}
221-
if (p.getMaxRetries() < 2) {
222-
throw new IllegalArgumentException("Max retries must be ≥ 2");
223-
}
224-
}
225213
}

src/main/java/com/mindee/http/MindeeApiV2.java

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
package com.mindee.http;
22

3+
import com.mindee.MindeeException;
34
import com.mindee.input.LocalInputSource;
45
import com.mindee.input.URLInputSource;
56
import com.mindee.parsing.v2.CommonResponse;
67
import com.mindee.parsing.v2.ErrorResponse;
78
import com.mindee.parsing.v2.JobResponse;
89
import com.mindee.v2.clientOptions.BaseParameters;
10+
import com.mindee.v2.http.ProductInfo;
911
import java.io.IOException;
1012

1113
/**
@@ -63,4 +65,24 @@ protected ErrorResponse makeUnknownError(int statusCode) {
6365
null
6466
);
6567
}
68+
69+
protected ProductInfo getResponseProductInfo(Class<? extends CommonResponse> responseClass) {
70+
ProductInfo productInfo = responseClass.getAnnotation(ProductInfo.class);
71+
if (productInfo == null) {
72+
throw new MindeeException(
73+
"The class " + responseClass.getSimpleName() + " is not annotated with @ProductInfo"
74+
);
75+
}
76+
return productInfo;
77+
}
78+
79+
protected ProductInfo getParamsProductInfo(Class<? extends BaseParameters> responseClass) {
80+
ProductInfo productInfo = responseClass.getAnnotation(ProductInfo.class);
81+
if (productInfo == null) {
82+
throw new MindeeException(
83+
"The class " + responseClass.getSimpleName() + " is not annotated with @ProductInfo"
84+
);
85+
}
86+
return productInfo;
87+
}
6688
}

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

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import com.mindee.parsing.v2.ErrorResponse;
1010
import com.mindee.parsing.v2.JobResponse;
1111
import com.mindee.v2.clientOptions.BaseParameters;
12+
import com.mindee.v2.http.ProductInfo;
1213
import java.io.IOException;
1314
import java.net.URISyntaxException;
1415
import java.nio.charset.StandardCharsets;
@@ -68,8 +69,9 @@ private MindeeHttpApiV2(MindeeSettingsV2 mindeeSettings, HttpClientBuilder httpC
6869
*/
6970
@Override
7071
public JobResponse reqPostEnqueue(LocalInputSource inputSource, BaseParameters options) {
72+
ProductInfo productInfo = getParamsProductInfo(options.getClass());
7173
String url = String
72-
.format("%s/products/%s/enqueue", this.mindeeSettings.getBaseUrl(), options.getSlug());
74+
.format("%s/products/%s/enqueue", this.mindeeSettings.getBaseUrl(), productInfo.slug());
7375
HttpPost post = buildHttpPost(url);
7476

7577
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
@@ -94,8 +96,9 @@ public JobResponse reqPostEnqueue(LocalInputSource inputSource, BaseParameters o
9496
*/
9597
@Override
9698
public JobResponse reqPostEnqueue(URLInputSource inputSource, BaseParameters options) {
99+
ProductInfo productInfo = getParamsProductInfo(options.getClass());
97100
String url = String
98-
.format("%s/products/%s/enqueue", this.mindeeSettings.getBaseUrl(), options.getSlug());
101+
.format("%s/products/%s/enqueue", this.mindeeSettings.getBaseUrl(), productInfo.slug());
99102
HttpPost post = buildHttpPost(url);
100103

101104
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
@@ -172,8 +175,14 @@ public <TResponse extends CommonResponse> TResponse reqGetResult(
172175
Class<TResponse> responseClass,
173176
String inferenceId
174177
) {
175-
176-
String url = this.mindeeSettings.getBaseUrl() + "/products/extraction/results/" + inferenceId;
178+
ProductInfo productInfo = getResponseProductInfo(responseClass);
179+
String url = String
180+
.format(
181+
"%s/products/%s/results/%s",
182+
this.mindeeSettings.getBaseUrl(),
183+
productInfo.slug(),
184+
inferenceId
185+
);
177186
HttpGet get = new HttpGet(url);
178187

179188
if (this.mindeeSettings.getApiKey().isPresent()) {

src/main/java/com/mindee/parsing/v2/InferenceResponse.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
11
package com.mindee.parsing.v2;
22

3+
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
34
import com.fasterxml.jackson.annotation.JsonProperty;
5+
import com.mindee.v2.http.ProductInfo;
46
import lombok.Getter;
57

68
/**
79
* Response for an extraction inference.
810
*/
911
@Getter
12+
@JsonIgnoreProperties(ignoreUnknown = true)
13+
@ProductInfo(slug = "extraction")
1014
public class InferenceResponse extends CommonResponse {
1115

1216
/**

src/main/java/com/mindee/v2/clientOptions/BaseParameters.java

Lines changed: 48 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.mindee.v2.clientOptions;
22

33
import com.mindee.AsyncPollingOptions;
4+
import java.util.Objects;
45
import lombok.Data;
56
import org.apache.hc.client5.http.entity.mime.MultipartEntityBuilder;
67

@@ -23,10 +24,6 @@ public abstract class BaseParameters {
2324
* Polling options. Set only if having timeout issues.
2425
*/
2526
protected final AsyncPollingOptions pollingOptions;
26-
/**
27-
* Slug of the product type.
28-
*/
29-
private final String slug;
3027

3128
public MultipartEntityBuilder buildHttpBody(MultipartEntityBuilder builder) {
3229
builder.addTextBody("model_id", this.getModelId());
@@ -38,4 +35,51 @@ public MultipartEntityBuilder buildHttpBody(MultipartEntityBuilder builder) {
3835
}
3936
return builder;
4037
}
38+
39+
public void validatePollingOptions() {
40+
if (pollingOptions.getInitialDelaySec() < 1) {
41+
throw new IllegalArgumentException("Initial delay must be ≥ 1 s");
42+
}
43+
if (pollingOptions.getIntervalSec() < 1) {
44+
throw new IllegalArgumentException("Interval must be ≥ 1 s");
45+
}
46+
if (pollingOptions.getMaxRetries() < 2) {
47+
throw new IllegalArgumentException("Max retries must be ≥ 2");
48+
}
49+
}
50+
51+
protected static abstract class BaseBuilder<T extends BaseBuilder<T>> {
52+
protected final String modelId;
53+
protected String alias;
54+
protected String[] webhookIds = new String[] {};
55+
protected AsyncPollingOptions pollingOptions = AsyncPollingOptions.builder().build();
56+
57+
@SuppressWarnings("unchecked")
58+
protected T self() {
59+
return (T) this;
60+
}
61+
62+
protected BaseBuilder(String modelId) {
63+
this.modelId = Objects.requireNonNull(modelId, "modelId must not be null");
64+
}
65+
66+
/** Set an alias for the uploaded document. */
67+
public T alias(String alias) {
68+
this.alias = alias;
69+
return self();
70+
}
71+
72+
/** Provide IDs of webhooks to forward the API response to. */
73+
public T webhookIds(String[] webhookIds) {
74+
this.webhookIds = webhookIds;
75+
return self();
76+
}
77+
78+
/** Set polling options. */
79+
public T pollingOptions(AsyncPollingOptions pollingOptions) {
80+
this.pollingOptions = pollingOptions;
81+
return self();
82+
}
83+
}
84+
4185
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package com.mindee.v2.http;
2+
3+
import java.lang.annotation.Documented;
4+
import java.lang.annotation.ElementType;
5+
import java.lang.annotation.Retention;
6+
import java.lang.annotation.RetentionPolicy;
7+
import java.lang.annotation.Target;
8+
9+
/**
10+
* Base info for all v2 products.
11+
*/
12+
@Documented
13+
@Target(ElementType.TYPE)
14+
@Retention(RetentionPolicy.RUNTIME)
15+
public @interface ProductInfo {
16+
String slug();
17+
}

src/main/java/com/mindee/v2/product/classification/ClassificationResponse.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,15 @@
33
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
44
import com.fasterxml.jackson.annotation.JsonProperty;
55
import com.mindee.parsing.v2.CommonResponse;
6+
import com.mindee.v2.http.ProductInfo;
67
import lombok.Getter;
78

89
/**
910
* Response for a classification utility inference.
1011
*/
1112
@Getter
1213
@JsonIgnoreProperties(ignoreUnknown = true)
14+
@ProductInfo(slug = "classification")
1315
public class ClassificationResponse extends CommonResponse {
1416

1517
/**

src/main/java/com/mindee/v2/product/crop/CropResponse.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,15 @@
33
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
44
import com.fasterxml.jackson.annotation.JsonProperty;
55
import com.mindee.parsing.v2.CommonResponse;
6+
import com.mindee.v2.http.ProductInfo;
67
import lombok.Getter;
78

89
/**
910
* Response for a crop utility inference.
1011
*/
1112
@Getter
1213
@JsonIgnoreProperties(ignoreUnknown = true)
14+
@ProductInfo(slug = "crop")
1315
public class CropResponse extends CommonResponse {
1416

1517
/**

0 commit comments

Comments
 (0)