Skip to content

Commit 58c4926

Browse files
authored
🔖 Version 5.0.0-beta2 (#327)
* ♻️ put error parsing in its own package * ✨ add model search API
1 parent 631c85a commit 58c4926

23 files changed

Lines changed: 348 additions & 83 deletions

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
# Mindee Java Client Library Changelog
22

3+
## v5.0.0-beta2 - 2026-05-20
4+
### ¡Breaking Changes!
5+
* :recycle: put error parsing in its own package
6+
### Changes
7+
* :sparkles: add model search API
8+
9+
310
## v5.0.0-beta1 - 2026-05-06
411
### ¡Breaking Changes!
512
* :coffin: Remove obsolete/unused products:

docs/code_samples/v2_classification.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ public class SimpleMindeeClientV2 {
1010
throws IOException, InterruptedException
1111
{
1212
String apiKey = "MY_API_KEY";
13-
String filePath = "/path/to/the/file.ext";
1413
String modelId = "MY_MODEL_ID";
14+
String filePath = "/path/to/the/file.ext";
1515

1616
// Init a new client
1717
var mindeeClient = new MindeeClient(apiKey);
@@ -38,6 +38,6 @@ public class SimpleMindeeClientV2 {
3838

3939
// Access the classification result
4040
var result = response.getInference().getResult();
41-
var classification = result.getClassification();
41+
String documentType = result.getClassification().getDocumentType();
4242
}
4343
}

docs/code_samples/v2_crop.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ public class SimpleMindeeClientV2 {
1010
throws IOException, InterruptedException
1111
{
1212
String apiKey = "MY_API_KEY";
13-
String filePath = "/path/to/the/file.ext";
1413
String modelId = "MY_MODEL_ID";
14+
String filePath = "/path/to/the/file.ext";
1515

1616
// Init a new client
1717
var mindeeClient = new MindeeClient(apiKey);
@@ -36,6 +36,6 @@ public class SimpleMindeeClientV2 {
3636
System.out.println(response.getInference().toString());
3737

3838
// Access the crop results
39-
var result = response.getInference().getResult();
39+
var crops = response.getInference().getResult().getCrops();
4040
}
4141
}

docs/code_samples/v2_extraction.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ public class SimpleMindeeClientV2 {
1010
throws IOException, InterruptedException
1111
{
1212
String apiKey = "MY_API_KEY";
13-
String filePath = "/path/to/the/file.ext";
1413
String modelId = "MY_MODEL_ID";
14+
String filePath = "/path/to/the/file.ext";
1515

1616
// Init a new client
1717
var mindeeClient = new MindeeClient(apiKey);

docs/code_samples/v2_ocr.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,6 @@ public class SimpleMindeeClientV2 {
3636
System.out.println(response.getInference().toString());
3737

3838
// Access the result OCR pages
39-
var result = response.getInference().getResult();
39+
var pages = response.getInference().getResult().getPages();
4040
}
4141
}

docs/code_samples/v2_split.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ public class SimpleMindeeClientV2 {
1010
throws IOException, InterruptedException
1111
{
1212
String apiKey = "MY_API_KEY";
13-
String filePath = "/path/to/the/file.ext";
1413
String modelId = "MY_MODEL_ID";
14+
String filePath = "/path/to/the/file.ext";
1515

1616
// Init a new client
1717
var mindeeClient = new MindeeClient(apiKey);
@@ -36,6 +36,6 @@ public class SimpleMindeeClientV2 {
3636
System.out.println(response.getInference().toString());
3737

3838
// Access the split result
39-
var result = response.getInference().getResult();
39+
var splits = response.getInference().getResult().getSplits();
4040
}
4141
}

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -372,7 +372,7 @@
372372

373373
<properties>
374374
<!-- MINDEE VERSION GOES HERE -->
375-
<revision>5.0.0-beta1</revision>
375+
<revision>5.0.0-beta2</revision>
376376

377377
<!-- Give special access when running tests -->
378378
<surefire.addOpens>

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

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,9 @@
88
import com.mindee.v2.http.MindeeHttpApiV2;
99
import com.mindee.v2.http.MindeeHttpExceptionV2;
1010
import com.mindee.v2.parsing.CommonResponse;
11-
import com.mindee.v2.parsing.ErrorResponse;
1211
import com.mindee.v2.parsing.JobResponse;
12+
import com.mindee.v2.parsing.error.ErrorResponse;
13+
import com.mindee.v2.parsing.search.SearchResponse;
1314
import com.mindee.v2.product.extraction.ExtractionResponse;
1415
import java.io.IOException;
1516

@@ -172,6 +173,36 @@ public <TResponse extends CommonResponse> TResponse enqueueAndGetResult(
172173
return pollAndFetch(responseClass, job, pollingOptions);
173174
}
174175

176+
/**
177+
* Return all models.
178+
*
179+
* @return an instance of {@link SearchResponse}
180+
*/
181+
public SearchResponse searchModels() {
182+
return searchModels(null, null);
183+
}
184+
185+
/**
186+
* Search for models by name.
187+
*
188+
* @param modelName name of the model to search for
189+
* @return an instance of {@link SearchResponse}
190+
*/
191+
public SearchResponse searchModels(String modelName) {
192+
return searchModels(modelName, null);
193+
}
194+
195+
/**
196+
* Search for models by name and type.
197+
*
198+
* @param modelName name of the model to search for
199+
* @param modelType type of the model to search for
200+
* @return an instance of {@link SearchResponse}
201+
*/
202+
public SearchResponse searchModels(String modelName, String modelType) {
203+
return mindeeApi.reqGetSearchModels(modelName, modelType);
204+
}
205+
175206
/**
176207
* Common logic for polling an asynchronous job for local & url files.
177208
*

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

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,9 @@
66
import com.mindee.input.URLInputSource;
77
import com.mindee.v2.clientoptions.BaseParameters;
88
import com.mindee.v2.parsing.CommonResponse;
9-
import com.mindee.v2.parsing.ErrorResponse;
109
import com.mindee.v2.parsing.JobResponse;
10+
import com.mindee.v2.parsing.error.ErrorResponse;
11+
import com.mindee.v2.parsing.search.SearchResponse;
1112
import java.io.IOException;
1213

1314
/**
@@ -48,11 +49,19 @@ public abstract JobResponse reqPostEnqueue(
4849
*
4950
* @param inferenceId ID of the inference to poll.
5051
*/
51-
abstract public <TResponse extends CommonResponse> TResponse reqGetResult(
52+
public abstract <TResponse extends CommonResponse> TResponse reqGetResult(
5253
Class<TResponse> responseClass,
5354
String inferenceId
5455
);
5556

57+
/**
58+
* Retrieves a list of models.
59+
*
60+
* @param modelName search term for model name
61+
* @param modelType search term for model type
62+
*/
63+
public abstract SearchResponse reqGetSearchModels(String modelName, String modelType);
64+
5665
/**
5766
* Creates an "unknown error" response from an HTTP status code.
5867
*/

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

Lines changed: 47 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,16 @@
88
import com.mindee.v2.MindeeSettings;
99
import com.mindee.v2.clientoptions.BaseParameters;
1010
import com.mindee.v2.parsing.CommonResponse;
11-
import com.mindee.v2.parsing.ErrorResponse;
1211
import com.mindee.v2.parsing.JobResponse;
12+
import com.mindee.v2.parsing.error.ErrorResponse;
13+
import com.mindee.v2.parsing.search.SearchResponse;
1314
import java.io.IOException;
1415
import java.net.URISyntaxException;
1516
import java.nio.charset.StandardCharsets;
1617
import lombok.Builder;
1718
import org.apache.hc.client5.http.classic.methods.HttpGet;
1819
import org.apache.hc.client5.http.classic.methods.HttpPost;
20+
import org.apache.hc.client5.http.classic.methods.HttpUriRequestBase;
1921
import org.apache.hc.client5.http.config.RequestConfig;
2022
import org.apache.hc.client5.http.entity.mime.HttpMultipartMode;
2123
import org.apache.hc.client5.http.entity.mime.MultipartEntityBuilder;
@@ -82,7 +84,7 @@ public JobResponse reqPostEnqueue(LocalInputSource inputSource, BaseParameters o
8284
inputSource.getFilename()
8385
);
8486
post.setEntity(options.buildHttpBody(builder).build());
85-
return executeEnqueue(post);
87+
return executeAPIRequest(post, JobResponse.class);
8688
}
8789

8890
/**
@@ -103,33 +105,7 @@ public JobResponse reqPostEnqueue(URLInputSource inputSource, BaseParameters opt
103105
builder.setMode(HttpMultipartMode.EXTENDED);
104106
builder.addTextBody("url", inputSource.getUrl().toString());
105107
post.setEntity(options.buildHttpBody(builder).build());
106-
return executeEnqueue(post);
107-
}
108-
109-
/**
110-
* Executes an enqueue action, common to URL & local inputs.
111-
*
112-
* @param post HTTP Post object.
113-
* @return a valid job response.
114-
*/
115-
private JobResponse executeEnqueue(HttpPost post) {
116-
try (var httpClient = httpClientBuilder.build()) {
117-
return httpClient.execute(post, response -> {
118-
var responseEntity = response.getEntity();
119-
var statusCode = response.getCode();
120-
if (isInvalidStatusCode(statusCode)) {
121-
throw getHttpError(response);
122-
}
123-
try {
124-
var raw = EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8);
125-
return deserializeOrThrow(raw, JobResponse.class, response.getCode());
126-
} finally {
127-
EntityUtils.consumeQuietly(responseEntity);
128-
}
129-
});
130-
} catch (IOException err) {
131-
throw new MindeeException(err.getMessage(), err);
132-
}
108+
return executeAPIRequest(post, JobResponse.class);
133109
}
134110

135111
@Override
@@ -138,31 +114,10 @@ public JobResponse reqGetJob(String jobId) {
138114
var url = this.mindeeSettings.getBaseUrl() + "/jobs/" + jobId;
139115
var get = new HttpGet(url);
140116

141-
if (this.mindeeSettings.getApiKey().isPresent()) {
142-
get.setHeader(HttpHeaders.AUTHORIZATION, this.mindeeSettings.getApiKey().get());
143-
}
144-
get.setHeader(HttpHeaders.USER_AGENT, getUserAgent());
145117
var noRedirect = RequestConfig.custom().setRedirectsEnabled(false).build();
146118
get.setConfig(noRedirect);
147119

148-
try (var httpClient = httpClientBuilder.build()) {
149-
return httpClient.execute(get, response -> {
150-
var responseEntity = response.getEntity();
151-
var statusCode = response.getCode();
152-
if (isInvalidStatusCode(statusCode)) {
153-
throw getHttpError(response);
154-
}
155-
try {
156-
var raw = EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8);
157-
158-
return deserializeOrThrow(raw, JobResponse.class, response.getCode());
159-
} finally {
160-
EntityUtils.consumeQuietly(responseEntity);
161-
}
162-
});
163-
} catch (IOException err) {
164-
throw new MindeeException(err.getMessage(), err);
165-
}
120+
return this.executeAPIRequest(get, JobResponse.class);
166121
}
167122

168123
@Override
@@ -179,25 +134,54 @@ public <TResponse extends CommonResponse> TResponse reqGetResult(
179134
inferenceId
180135
);
181136
var get = new HttpGet(url);
137+
return executeAPIRequest(get, responseClass);
138+
}
182139

140+
@Override
141+
public SearchResponse reqGetSearchModels(String modelName, String modelType) {
142+
URIBuilder url;
143+
try {
144+
url = new URIBuilder(this.mindeeSettings.getBaseUrl() + "/search/models");
145+
} catch (URISyntaxException e) {
146+
throw new RuntimeException(e);
147+
}
148+
if (modelName != null) {
149+
url.addParameter("name", modelName);
150+
}
151+
if (modelType != null) {
152+
url.addParameter("type", modelType);
153+
}
154+
var get = new HttpGet(url.toString());
155+
return executeAPIRequest(get, SearchResponse.class);
156+
}
157+
158+
/**
159+
* Executes an enqueue action, common to URL & local inputs.
160+
*
161+
* @param apiRequest HTTP request object.
162+
* @return a valid job response.
163+
*/
164+
private <TResponse extends CommonResponse> TResponse executeAPIRequest(
165+
HttpUriRequestBase apiRequest,
166+
Class<TResponse> responseClass
167+
) {
183168
if (this.mindeeSettings.getApiKey().isPresent()) {
184-
get.setHeader(HttpHeaders.AUTHORIZATION, this.mindeeSettings.getApiKey().get());
169+
apiRequest.setHeader(HttpHeaders.AUTHORIZATION, this.mindeeSettings.getApiKey().get());
185170
}
186-
get.setHeader(HttpHeaders.USER_AGENT, getUserAgent());
171+
apiRequest.setHeader(HttpHeaders.USER_AGENT, getUserAgent());
187172

188173
try (var httpClient = httpClientBuilder.build()) {
189-
190-
return httpClient.execute(get, response -> {
191-
var entity = response.getEntity();
192-
var status = response.getCode();
174+
return httpClient.execute(apiRequest, response -> {
175+
var responseEntity = response.getEntity();
176+
var statusCode = response.getCode();
177+
if (isInvalidStatusCode(statusCode)) {
178+
throw getHttpError(response);
179+
}
193180
try {
194-
if (isInvalidStatusCode(status)) {
195-
throw getHttpError(response);
196-
}
197-
var raw = EntityUtils.toString(entity, StandardCharsets.UTF_8);
198-
return deserializeOrThrow(raw, responseClass, status);
181+
var raw = EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8);
182+
return deserializeOrThrow(raw, responseClass, response.getCode());
199183
} finally {
200-
EntityUtils.consumeQuietly(entity);
184+
EntityUtils.consumeQuietly(responseEntity);
201185
}
202186
});
203187
} catch (IOException err) {
@@ -235,11 +219,6 @@ private HttpPost buildHttpPost(String url) {
235219
catch (URISyntaxException err) {
236220
return new HttpPost("invalid URI");
237221
}
238-
239-
if (this.mindeeSettings.getApiKey().isPresent()) {
240-
post.setHeader(HttpHeaders.AUTHORIZATION, this.mindeeSettings.getApiKey().get());
241-
}
242-
post.setHeader(HttpHeaders.USER_AGENT, getUserAgent());
243222
return post;
244223
}
245224

0 commit comments

Comments
 (0)