Skip to content

Commit ef5f559

Browse files
code-c-lightmengqian
andauthored
feat: support file parsing sync (#60)
Co-authored-by: mengqian <[email protected]>
1 parent 67bd991 commit ef5f559

File tree

8 files changed

+177
-42
lines changed

8 files changed

+177
-42
lines changed

core/src/main/java/ai/z/openapi/api/fileparsing/FileParsingApi.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,4 +44,14 @@ public interface FileParsingApi {
4444
@GET("files/parser/result/{taskId}/{formatType}")
4545
Call<ResponseBody> downloadParseResult(@Path("taskId") String taskId, @Path("formatType") String formatType);
4646

47+
/**
48+
* Executes a synchronous file parsing operation. Uploads a file and returns the
49+
* parsing result with specified tool and file type.
50+
* @param multipartBody The multipart request body containing the file and related
51+
* metadata (tool type, file type)
52+
* @return Parsing result content as a FileParsingDownloadResp object
53+
*/
54+
@POST("files/parser/sync")
55+
Call<FileParsingDownloadResp> syncParse(@Body MultipartBody multipartBody);
56+
4757
}

core/src/main/java/ai/z/openapi/core/Constants.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,9 @@
33
/**
44
* Constants class containing all the configuration values and model identifiers used
55
* throughout the Z.AI OpenAPI SDK.
6-
*
6+
* <p>
77
* This class provides centralized access to: - API base URLs - Model identifiers for
88
* different AI capabilities - Invocation method constants
9-
*
109
*/
1110
public final class Constants {
1211

core/src/main/java/ai/z/openapi/service/fileparsing/FileParsingService.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,13 @@ public interface FileParsingService {
2020
*/
2121
FileParsingDownloadResponse getParseResult(FileParsingDownloadReq request);
2222

23+
/**
24+
* Executes a synchronous file parsing operation. Uploads a file and immediately
25+
* returns the parsing result, using the specified tool and file type.
26+
* @param request The file parsing upload request (contains file path, tool type, file
27+
* type, etc.)
28+
* @return FileParsingDownloadResponse containing the parsed content and status
29+
*/
30+
FileParsingDownloadResponse syncParse(FileParsingUploadReq request);
31+
2332
}

core/src/main/java/ai/z/openapi/service/fileparsing/FileParsingServiceImpl.java

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ public FileParsingResponse createParseTask(FileParsingUploadReq request) {
4040
if (request.getToolType() == null) {
4141
throw new IllegalArgumentException("toolType cannot be null");
4242
}
43-
// 构建 multipart/form-data
43+
// Construct multipart/form-data
4444
RequestSupplier<FileParsingUploadReq, FileParsingUploadResp> supplier = params -> {
4545
try {
4646
File file = new File(params.getFilePath());
@@ -107,4 +107,55 @@ public FileParsingDownloadResponse getParseResult(FileParsingDownloadReq request
107107
return this.zAiClient.executeRequest(request, supplier, FileParsingDownloadResponse.class);
108108
}
109109

110+
@Override
111+
public FileParsingDownloadResponse syncParse(FileParsingUploadReq request) {
112+
if (request == null) {
113+
throw new IllegalArgumentException("request cannot be null");
114+
}
115+
if (request.getFilePath() == null) {
116+
throw new IllegalArgumentException("filePath cannot be null");
117+
}
118+
if (request.getToolType() == null) {
119+
throw new IllegalArgumentException("toolType cannot be null");
120+
}
121+
122+
RequestSupplier<FileParsingUploadReq, FileParsingDownloadResp> supplier = params -> {
123+
try {
124+
File file = new File(params.getFilePath());
125+
if (!file.exists()) {
126+
throw new RuntimeException("file not found at " + params.getFilePath());
127+
}
128+
129+
String toolType = params.getToolType();
130+
String fileType = params.getFileType();
131+
132+
// Construct multipart/form-data
133+
MultipartBody.Part filePart = MultipartBody.Part.createFormData("file", file.getName(),
134+
RequestBody.create(MediaType.parse("application/octet-stream"), file));
135+
MultipartBody.Builder formBodyBuilder = new MultipartBody.Builder().setType(MultipartBody.FORM);
136+
formBodyBuilder.addPart(filePart);
137+
formBodyBuilder.addFormDataPart("tool_type", toolType);
138+
formBodyBuilder.addFormDataPart("file_type", fileType);
139+
140+
MultipartBody multipartBody = formBodyBuilder.build();
141+
142+
// Send a POST request
143+
retrofit2.Call<FileParsingDownloadResp> call = fileParsingApi.syncParse(multipartBody);
144+
Response<FileParsingDownloadResp> response = call.execute();
145+
if (!response.isSuccessful() || response.body() == null) {
146+
throw new IOException(
147+
"Failed to sync parse, code: " + response.code() + ", msg: " + response.message());
148+
}
149+
150+
return Single.just(response.body());
151+
152+
}
153+
catch (Exception e) {
154+
throw new RuntimeException(e);
155+
}
156+
};
157+
158+
return this.zAiClient.executeRequest(request, supplier, FileParsingDownloadResponse.class);
159+
}
160+
110161
}

core/src/test/java/ai/z/openapi/service/fileparsing/FileParsingServiceTest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -218,11 +218,11 @@ void testCreateParseTaskWithImage() throws IOException {
218218
byte[] bytes = Files.readAllBytes(new File(file).toPath());
219219
Base64.Encoder encoder = Base64.getEncoder();
220220
String imageBase64 = encoder.encodeToString(bytes);
221-
// 假设解析接口支持 imageBase64 字段
221+
// Assuming the parsing interface supports the imageBase64 field
222222
FileParsingUploadReq request = FileParsingUploadReq.builder()
223223
.toolType("image")
224224
.fileType("png")
225-
.filePath(file) // 或文件路径
225+
.filePath(file) // file path
226226
.build();
227227

228228
FileParsingResponse response = fileParsingService.createParseTask(request);

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@
4545
</scm>
4646

4747
<properties>
48-
<revision>0.0.6.1</revision>
48+
<revision>0.0.6.2</revision>
4949
<java.version>8</java.version>
5050
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
5151
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>

samples/src/main/ai.z.openapi.samples/FileParsingExample.java

Lines changed: 38 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -10,84 +10,86 @@
1010
public class FileParsingExample {
1111

1212
public static void main(String[] args) {
13-
// 建议通过环境变量设置 API Key
14-
// export ZAI_API_KEY=your.api_key
15-
// ZaiClient client = ZaiClient.builder().build();
13+
// It's recommended to set the API Key via environment variable
14+
// export ZAI_API_KEY=your.api_key
15+
// ZaiClient client = ZaiClient.builder().build();
16+
17+
// You can also specify the API Key directly in code
18+
1619

17-
// 也可在代码中直接指定 API Key
1820
ZaiClient client = ZaiClient.builder()
1921
.apiKey("API Key")
2022
.build();
2123

2224
try {
23-
// 示例1: 创建解析任务
24-
System.out.println("=== 文件解析任务创建示例 ===");
25+
// Example 1: Create a file parsing task
26+
System.out.println("=== Example: Create file parsing task ===");
2527
String filePath = "your file path";
2628
String taskId = createFileParsingTaskExample(client, filePath, "pdf", "lite");
2729

28-
// 示例2: 获取解析结果
29-
System.out.println("\n=== 获取解析结果示例 ===");
30+
// Example 2: Get parsing result
31+
System.out.println("\n=== Example: Get parsing result ===");
3032
getFileParsingResultExample(client, taskId);
3133

3234
} catch (Exception e) {
33-
System.err.println("发生异常: " + e.getMessage());
35+
System.err.println("Exception occurred: " + e.getMessage());
3436
e.printStackTrace();
3537
}
3638
}
3739

3840
/**
39-
* 示例:创建解析任务(上传文件并解析)
41+
* Example: Create parsing task (upload file and parse)
4042
*
41-
* @param client ZaiClient 实例
42-
* @return 解析任务的 taskId
43+
* @param client ZaiClient instance
44+
* @return TaskId of the parsing task
4345
*/
4446
private static String createFileParsingTaskExample(ZaiClient client, String filePath, String fileType, String toolType) {
4547
if (StringUtils.isEmpty(filePath)) {
46-
System.err.println("无效的文件路径。");
48+
System.err.println("Invalid file path.");
4749
return null;
4850
}
4951
try {
5052
FileParsingUploadReq uploadReq = FileParsingUploadReq.builder()
5153
.filePath(filePath)
52-
.fileType(fileType) // 支持: pdf, docx
53-
.toolType(toolType) // 解析工具类型: lite, prime, expert
54+
.fileType(fileType) // support: pdf, docx etc.
55+
.toolType(toolType) // tool type: lite, prime, expert
5456
.build();
5557

56-
System.out.println("正在上传并创建解析任务...");
58+
System.out.println("Uploading file and creating parsing task...");
5759
FileParsingResponse response = client.fileParsing().createParseTask(uploadReq);
5860
if (response.isSuccess()) {
5961
if (null != response.getData().getTaskId()) {
6062
String taskId = response.getData().getTaskId();
61-
System.out.println("解析任务创建成功,TaskId: " + taskId);
63+
System.out.println("Parsing task created successfully, TaskId: " + taskId);
6264
return taskId;
6365
} else {
64-
System.err.println("解析任务创建失败: " + response.getData().getMessage());
66+
System.err.println("Failed to create parsing task: " + response.getData().getMessage());
6567
}
6668
} else {
67-
System.err.println("解析任务创建失败: " + response.getMsg());
69+
System.err.println("Failed to create parsing task: " + response.getMsg());
6870
}
6971
} catch (Exception e) {
70-
System.err.println("文件解析任务错误: " + e.getMessage());
72+
System.err.println("File parsing task error: " + e.getMessage());
7173
}
72-
// 返回 null 表示创建失败
74+
// Return null indicates task creation failed
7375
return null;
7476
}
7577

7678
/**
77-
* 示例:获取解析结果
79+
* Example: Get parsing result
7880
*
79-
* @param client ZaiClient 实例
80-
* @param taskId 解析任务ID
81+
* @param client ZaiClient instance
82+
* @param taskId ID of the parsing task
8183
*/
8284
private static void getFileParsingResultExample(ZaiClient client, String taskId) {
8385
if (taskId == null || taskId.isEmpty()) {
84-
System.err.println("无效的任务ID,无法获取解析结果。");
86+
System.err.println("Invalid task ID. Cannot get parsing result.");
8587
return;
8688
}
8789

8890
try {
89-
int maxRetry = 100; // 最多轮询100次
90-
int intervalMs = 3000; // 每次间隔3秒
91+
int maxRetry = 100; // Maximum 100 polling attempts
92+
int intervalMs = 3000; // 3 seconds interval between each polling
9193
for (int i = 0; i < maxRetry; i++) {
9294
FileParsingDownloadReq downloadReq = FileParsingDownloadReq.builder()
9395
.taskId(taskId)
@@ -98,28 +100,28 @@ private static void getFileParsingResultExample(ZaiClient client, String taskId)
98100

99101
if (response.isSuccess()) {
100102
String status = response.getData().getStatus();
101-
System.out.println("当前任务状态: " + status);
103+
System.out.println("Current task status: " + status);
102104

103105
if ("succeeded".equalsIgnoreCase(status)) {
104-
System.out.println("解析结果获取成功!");
105-
System.out.println("解析内容: " + response.getData().getContent());
106-
System.out.println("内容下载链接: " + response.getData().getParsingResultUrl());
106+
System.out.println("Parsing result obtained successfully!");
107+
System.out.println("Parsed content: " + response.getData().getContent());
108+
System.out.println("Download link: " + response.getData().getParsingResultUrl());
107109
return;
108110
} else if ("processing".equalsIgnoreCase(status)) {
109-
System.out.println("解析进行中,请稍候...");
111+
System.out.println("Parsing in progress, please wait...");
110112
Thread.sleep(intervalMs);
111113
} else {
112-
System.out.println("解析任务异常,状态: " + status + ",消息: " + response.getData().getMessage());
114+
System.out.println("Parsing task exception, status: " + status + ", message: " + response.getData().getMessage());
113115
return;
114116
}
115117
} else {
116-
System.err.println("解析结果获取失败: " + response.getMsg());
118+
System.err.println("Failed to get parsing result: " + response.getMsg());
117119
return;
118120
}
119121
}
120-
System.out.println("等待超时,请稍后自行查询解析结果。");
122+
System.out.println("Wait timeout, please check the parsing result later.");
121123
} catch (Exception e) {
122-
System.err.println("获取解析结果时异常: " + e.getMessage());
124+
System.err.println("Exception occurred while getting parsing result: " + e.getMessage());
123125
}
124126
}
125127
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
package ai.z.openapi.samples;
2+
3+
import ai.z.openapi.ZaiClient;
4+
import ai.z.openapi.service.fileparsing.FileParsingDownloadResponse;
5+
import ai.z.openapi.service.fileparsing.FileParsingUploadReq;
6+
import ai.z.openapi.utils.StringUtils;
7+
8+
public class FileParsingSyncExample {
9+
10+
public static void main(String[] args) {
11+
// It is recommended to set the API Key using an environment variable
12+
// export ZAI_API_KEY=your.api_key
13+
// ZaiClient client = ZaiClient.builder().build();
14+
15+
// Alternatively, the API Key can be specified directly in the code
16+
ZaiClient client = ZaiClient.builder()
17+
.apiKey("API Key")
18+
.build();
19+
20+
try {
21+
System.out.println("=== Example: Creating file parsing task ===");
22+
23+
String filePath = "your file path";
24+
FileParsingDownloadResponse result = syncFileParsingTaskExample(client, filePath, "pdf", "prime-sync");
25+
26+
System.out.println("Parsing task created successfully, TaskId: " + result.getData().getTaskId());
27+
System.out.println("File content: " + result.getData().getContent());
28+
System.out.println("Download link: " + result.getData().getParsingResultUrl());
29+
30+
} catch (Exception e) {
31+
System.err.println("Exception occurred: " + e.getMessage());
32+
e.printStackTrace();
33+
}
34+
}
35+
36+
/**
37+
* Example: Create parsing task (upload file and parse)
38+
*
39+
* @param client ZaiClient instance
40+
* @return Parsing task's taskId
41+
*/
42+
private static FileParsingDownloadResponse syncFileParsingTaskExample(ZaiClient client, String filePath, String fileType, String toolType) {
43+
if (StringUtils.isEmpty(filePath)) {
44+
System.err.println("Invalid file path.");
45+
return null;
46+
}
47+
try {
48+
FileParsingUploadReq uploadReq = FileParsingUploadReq.builder()
49+
.filePath(filePath)
50+
.fileType(fileType) // Supported types: pdf, docx, etc.
51+
.toolType(toolType) // Parsing tool type: lite, prime, expert
52+
.build();
53+
54+
System.out.println("Uploading file and creating parsing task...");
55+
return client.fileParsing().syncParse(uploadReq);
56+
} catch (Exception e) {
57+
System.err.println("File parsing task error: " + e.getMessage());
58+
}
59+
// Returning null means task creation failed
60+
return null;
61+
}
62+
63+
64+
}

0 commit comments

Comments
 (0)