feat: support file parsing sync (#60)
Co-authored-by: mengqian <cherish_a_meng@163.com>
This commit is contained in:
parent
67bd9910e1
commit
ef5f55982e
8 changed files with 177 additions and 42 deletions
|
|
@ -44,4 +44,14 @@ public interface FileParsingApi {
|
||||||
@GET("files/parser/result/{taskId}/{formatType}")
|
@GET("files/parser/result/{taskId}/{formatType}")
|
||||||
Call<ResponseBody> downloadParseResult(@Path("taskId") String taskId, @Path("formatType") String formatType);
|
Call<ResponseBody> downloadParseResult(@Path("taskId") String taskId, @Path("formatType") String formatType);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Executes a synchronous file parsing operation. Uploads a file and returns the
|
||||||
|
* parsing result with specified tool and file type.
|
||||||
|
* @param multipartBody The multipart request body containing the file and related
|
||||||
|
* metadata (tool type, file type)
|
||||||
|
* @return Parsing result content as a FileParsingDownloadResp object
|
||||||
|
*/
|
||||||
|
@POST("files/parser/sync")
|
||||||
|
Call<FileParsingDownloadResp> syncParse(@Body MultipartBody multipartBody);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -3,10 +3,9 @@ package ai.z.openapi.core;
|
||||||
/**
|
/**
|
||||||
* Constants class containing all the configuration values and model identifiers used
|
* Constants class containing all the configuration values and model identifiers used
|
||||||
* throughout the Z.AI OpenAPI SDK.
|
* throughout the Z.AI OpenAPI SDK.
|
||||||
*
|
* <p>
|
||||||
* This class provides centralized access to: - API base URLs - Model identifiers for
|
* This class provides centralized access to: - API base URLs - Model identifiers for
|
||||||
* different AI capabilities - Invocation method constants
|
* different AI capabilities - Invocation method constants
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public final class Constants {
|
public final class Constants {
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -20,4 +20,13 @@ public interface FileParsingService {
|
||||||
*/
|
*/
|
||||||
FileParsingDownloadResponse getParseResult(FileParsingDownloadReq request);
|
FileParsingDownloadResponse getParseResult(FileParsingDownloadReq request);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Executes a synchronous file parsing operation. Uploads a file and immediately
|
||||||
|
* returns the parsing result, using the specified tool and file type.
|
||||||
|
* @param request The file parsing upload request (contains file path, tool type, file
|
||||||
|
* type, etc.)
|
||||||
|
* @return FileParsingDownloadResponse containing the parsed content and status
|
||||||
|
*/
|
||||||
|
FileParsingDownloadResponse syncParse(FileParsingUploadReq request);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -40,7 +40,7 @@ public class FileParsingServiceImpl implements FileParsingService {
|
||||||
if (request.getToolType() == null) {
|
if (request.getToolType() == null) {
|
||||||
throw new IllegalArgumentException("toolType cannot be null");
|
throw new IllegalArgumentException("toolType cannot be null");
|
||||||
}
|
}
|
||||||
// 构建 multipart/form-data
|
// Construct multipart/form-data
|
||||||
RequestSupplier<FileParsingUploadReq, FileParsingUploadResp> supplier = params -> {
|
RequestSupplier<FileParsingUploadReq, FileParsingUploadResp> supplier = params -> {
|
||||||
try {
|
try {
|
||||||
File file = new File(params.getFilePath());
|
File file = new File(params.getFilePath());
|
||||||
|
|
@ -107,4 +107,55 @@ public class FileParsingServiceImpl implements FileParsingService {
|
||||||
return this.zAiClient.executeRequest(request, supplier, FileParsingDownloadResponse.class);
|
return this.zAiClient.executeRequest(request, supplier, FileParsingDownloadResponse.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FileParsingDownloadResponse syncParse(FileParsingUploadReq request) {
|
||||||
|
if (request == null) {
|
||||||
|
throw new IllegalArgumentException("request cannot be null");
|
||||||
|
}
|
||||||
|
if (request.getFilePath() == null) {
|
||||||
|
throw new IllegalArgumentException("filePath cannot be null");
|
||||||
|
}
|
||||||
|
if (request.getToolType() == null) {
|
||||||
|
throw new IllegalArgumentException("toolType cannot be null");
|
||||||
|
}
|
||||||
|
|
||||||
|
RequestSupplier<FileParsingUploadReq, FileParsingDownloadResp> supplier = params -> {
|
||||||
|
try {
|
||||||
|
File file = new File(params.getFilePath());
|
||||||
|
if (!file.exists()) {
|
||||||
|
throw new RuntimeException("file not found at " + params.getFilePath());
|
||||||
|
}
|
||||||
|
|
||||||
|
String toolType = params.getToolType();
|
||||||
|
String fileType = params.getFileType();
|
||||||
|
|
||||||
|
// Construct multipart/form-data
|
||||||
|
MultipartBody.Part filePart = MultipartBody.Part.createFormData("file", file.getName(),
|
||||||
|
RequestBody.create(MediaType.parse("application/octet-stream"), file));
|
||||||
|
MultipartBody.Builder formBodyBuilder = new MultipartBody.Builder().setType(MultipartBody.FORM);
|
||||||
|
formBodyBuilder.addPart(filePart);
|
||||||
|
formBodyBuilder.addFormDataPart("tool_type", toolType);
|
||||||
|
formBodyBuilder.addFormDataPart("file_type", fileType);
|
||||||
|
|
||||||
|
MultipartBody multipartBody = formBodyBuilder.build();
|
||||||
|
|
||||||
|
// Send a POST request
|
||||||
|
retrofit2.Call<FileParsingDownloadResp> call = fileParsingApi.syncParse(multipartBody);
|
||||||
|
Response<FileParsingDownloadResp> response = call.execute();
|
||||||
|
if (!response.isSuccessful() || response.body() == null) {
|
||||||
|
throw new IOException(
|
||||||
|
"Failed to sync parse, code: " + response.code() + ", msg: " + response.message());
|
||||||
|
}
|
||||||
|
|
||||||
|
return Single.just(response.body());
|
||||||
|
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return this.zAiClient.executeRequest(request, supplier, FileParsingDownloadResponse.class);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -218,11 +218,11 @@ public class FileParsingServiceTest {
|
||||||
byte[] bytes = Files.readAllBytes(new File(file).toPath());
|
byte[] bytes = Files.readAllBytes(new File(file).toPath());
|
||||||
Base64.Encoder encoder = Base64.getEncoder();
|
Base64.Encoder encoder = Base64.getEncoder();
|
||||||
String imageBase64 = encoder.encodeToString(bytes);
|
String imageBase64 = encoder.encodeToString(bytes);
|
||||||
// 假设解析接口支持 imageBase64 字段
|
// Assuming the parsing interface supports the imageBase64 field
|
||||||
FileParsingUploadReq request = FileParsingUploadReq.builder()
|
FileParsingUploadReq request = FileParsingUploadReq.builder()
|
||||||
.toolType("image")
|
.toolType("image")
|
||||||
.fileType("png")
|
.fileType("png")
|
||||||
.filePath(file) // 或文件路径
|
.filePath(file) // file path
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
FileParsingResponse response = fileParsingService.createParseTask(request);
|
FileParsingResponse response = fileParsingService.createParseTask(request);
|
||||||
|
|
|
||||||
2
pom.xml
2
pom.xml
|
|
@ -45,7 +45,7 @@
|
||||||
</scm>
|
</scm>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<revision>0.0.6.1</revision>
|
<revision>0.0.6.2</revision>
|
||||||
<java.version>8</java.version>
|
<java.version>8</java.version>
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||||
|
|
|
||||||
|
|
@ -10,84 +10,86 @@ import ai.z.openapi.utils.StringUtils;
|
||||||
public class FileParsingExample {
|
public class FileParsingExample {
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
// 建议通过环境变量设置 API Key
|
// It's recommended to set the API Key via environment variable
|
||||||
// export ZAI_API_KEY=your.api_key
|
// export ZAI_API_KEY=your.api_key
|
||||||
// ZaiClient client = ZaiClient.builder().build();
|
// ZaiClient client = ZaiClient.builder().build();
|
||||||
|
|
||||||
|
// You can also specify the API Key directly in code
|
||||||
|
|
||||||
|
|
||||||
// 也可在代码中直接指定 API Key
|
|
||||||
ZaiClient client = ZaiClient.builder()
|
ZaiClient client = ZaiClient.builder()
|
||||||
.apiKey("API Key")
|
.apiKey("API Key")
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// 示例1: 创建解析任务
|
// Example 1: Create a file parsing task
|
||||||
System.out.println("=== 文件解析任务创建示例 ===");
|
System.out.println("=== Example: Create file parsing task ===");
|
||||||
String filePath = "your file path";
|
String filePath = "your file path";
|
||||||
String taskId = createFileParsingTaskExample(client, filePath, "pdf", "lite");
|
String taskId = createFileParsingTaskExample(client, filePath, "pdf", "lite");
|
||||||
|
|
||||||
// 示例2: 获取解析结果
|
// Example 2: Get parsing result
|
||||||
System.out.println("\n=== 获取解析结果示例 ===");
|
System.out.println("\n=== Example: Get parsing result ===");
|
||||||
getFileParsingResultExample(client, taskId);
|
getFileParsingResultExample(client, taskId);
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
System.err.println("发生异常: " + e.getMessage());
|
System.err.println("Exception occurred: " + e.getMessage());
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 示例:创建解析任务(上传文件并解析)
|
* Example: Create parsing task (upload file and parse)
|
||||||
*
|
*
|
||||||
* @param client ZaiClient 实例
|
* @param client ZaiClient instance
|
||||||
* @return 解析任务的 taskId
|
* @return TaskId of the parsing task
|
||||||
*/
|
*/
|
||||||
private static String createFileParsingTaskExample(ZaiClient client, String filePath, String fileType, String toolType) {
|
private static String createFileParsingTaskExample(ZaiClient client, String filePath, String fileType, String toolType) {
|
||||||
if (StringUtils.isEmpty(filePath)) {
|
if (StringUtils.isEmpty(filePath)) {
|
||||||
System.err.println("无效的文件路径。");
|
System.err.println("Invalid file path.");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
FileParsingUploadReq uploadReq = FileParsingUploadReq.builder()
|
FileParsingUploadReq uploadReq = FileParsingUploadReq.builder()
|
||||||
.filePath(filePath)
|
.filePath(filePath)
|
||||||
.fileType(fileType) // 支持: pdf, docx 等
|
.fileType(fileType) // support: pdf, docx etc.
|
||||||
.toolType(toolType) // 解析工具类型: lite, prime, expert
|
.toolType(toolType) // tool type: lite, prime, expert
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
System.out.println("正在上传并创建解析任务...");
|
System.out.println("Uploading file and creating parsing task...");
|
||||||
FileParsingResponse response = client.fileParsing().createParseTask(uploadReq);
|
FileParsingResponse response = client.fileParsing().createParseTask(uploadReq);
|
||||||
if (response.isSuccess()) {
|
if (response.isSuccess()) {
|
||||||
if (null != response.getData().getTaskId()) {
|
if (null != response.getData().getTaskId()) {
|
||||||
String taskId = response.getData().getTaskId();
|
String taskId = response.getData().getTaskId();
|
||||||
System.out.println("解析任务创建成功,TaskId: " + taskId);
|
System.out.println("Parsing task created successfully, TaskId: " + taskId);
|
||||||
return taskId;
|
return taskId;
|
||||||
} else {
|
} else {
|
||||||
System.err.println("解析任务创建失败: " + response.getData().getMessage());
|
System.err.println("Failed to create parsing task: " + response.getData().getMessage());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
System.err.println("解析任务创建失败: " + response.getMsg());
|
System.err.println("Failed to create parsing task: " + response.getMsg());
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
System.err.println("文件解析任务错误: " + e.getMessage());
|
System.err.println("File parsing task error: " + e.getMessage());
|
||||||
}
|
}
|
||||||
// 返回 null 表示创建失败
|
// Return null indicates task creation failed
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 示例:获取解析结果
|
* Example: Get parsing result
|
||||||
*
|
*
|
||||||
* @param client ZaiClient 实例
|
* @param client ZaiClient instance
|
||||||
* @param taskId 解析任务ID
|
* @param taskId ID of the parsing task
|
||||||
*/
|
*/
|
||||||
private static void getFileParsingResultExample(ZaiClient client, String taskId) {
|
private static void getFileParsingResultExample(ZaiClient client, String taskId) {
|
||||||
if (taskId == null || taskId.isEmpty()) {
|
if (taskId == null || taskId.isEmpty()) {
|
||||||
System.err.println("无效的任务ID,无法获取解析结果。");
|
System.err.println("Invalid task ID. Cannot get parsing result.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
int maxRetry = 100; // 最多轮询100次
|
int maxRetry = 100; // Maximum 100 polling attempts
|
||||||
int intervalMs = 3000; // 每次间隔3秒
|
int intervalMs = 3000; // 3 seconds interval between each polling
|
||||||
for (int i = 0; i < maxRetry; i++) {
|
for (int i = 0; i < maxRetry; i++) {
|
||||||
FileParsingDownloadReq downloadReq = FileParsingDownloadReq.builder()
|
FileParsingDownloadReq downloadReq = FileParsingDownloadReq.builder()
|
||||||
.taskId(taskId)
|
.taskId(taskId)
|
||||||
|
|
@ -98,28 +100,28 @@ public class FileParsingExample {
|
||||||
|
|
||||||
if (response.isSuccess()) {
|
if (response.isSuccess()) {
|
||||||
String status = response.getData().getStatus();
|
String status = response.getData().getStatus();
|
||||||
System.out.println("当前任务状态: " + status);
|
System.out.println("Current task status: " + status);
|
||||||
|
|
||||||
if ("succeeded".equalsIgnoreCase(status)) {
|
if ("succeeded".equalsIgnoreCase(status)) {
|
||||||
System.out.println("解析结果获取成功!");
|
System.out.println("Parsing result obtained successfully!");
|
||||||
System.out.println("解析内容: " + response.getData().getContent());
|
System.out.println("Parsed content: " + response.getData().getContent());
|
||||||
System.out.println("内容下载链接: " + response.getData().getParsingResultUrl());
|
System.out.println("Download link: " + response.getData().getParsingResultUrl());
|
||||||
return;
|
return;
|
||||||
} else if ("processing".equalsIgnoreCase(status)) {
|
} else if ("processing".equalsIgnoreCase(status)) {
|
||||||
System.out.println("解析进行中,请稍候...");
|
System.out.println("Parsing in progress, please wait...");
|
||||||
Thread.sleep(intervalMs);
|
Thread.sleep(intervalMs);
|
||||||
} else {
|
} else {
|
||||||
System.out.println("解析任务异常,状态: " + status + ",消息: " + response.getData().getMessage());
|
System.out.println("Parsing task exception, status: " + status + ", message: " + response.getData().getMessage());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
System.err.println("解析结果获取失败: " + response.getMsg());
|
System.err.println("Failed to get parsing result: " + response.getMsg());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
System.out.println("等待超时,请稍后自行查询解析结果。");
|
System.out.println("Wait timeout, please check the parsing result later.");
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
System.err.println("获取解析结果时异常: " + e.getMessage());
|
System.err.println("Exception occurred while getting parsing result: " + e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,64 @@
|
||||||
|
package ai.z.openapi.samples;
|
||||||
|
|
||||||
|
import ai.z.openapi.ZaiClient;
|
||||||
|
import ai.z.openapi.service.fileparsing.FileParsingDownloadResponse;
|
||||||
|
import ai.z.openapi.service.fileparsing.FileParsingUploadReq;
|
||||||
|
import ai.z.openapi.utils.StringUtils;
|
||||||
|
|
||||||
|
public class FileParsingSyncExample {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
// It is recommended to set the API Key using an environment variable
|
||||||
|
// export ZAI_API_KEY=your.api_key
|
||||||
|
// ZaiClient client = ZaiClient.builder().build();
|
||||||
|
|
||||||
|
// Alternatively, the API Key can be specified directly in the code
|
||||||
|
ZaiClient client = ZaiClient.builder()
|
||||||
|
.apiKey("API Key")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
try {
|
||||||
|
System.out.println("=== Example: Creating file parsing task ===");
|
||||||
|
|
||||||
|
String filePath = "your file path";
|
||||||
|
FileParsingDownloadResponse result = syncFileParsingTaskExample(client, filePath, "pdf", "prime-sync");
|
||||||
|
|
||||||
|
System.out.println("Parsing task created successfully, TaskId: " + result.getData().getTaskId());
|
||||||
|
System.out.println("File content: " + result.getData().getContent());
|
||||||
|
System.out.println("Download link: " + result.getData().getParsingResultUrl());
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.err.println("Exception occurred: " + e.getMessage());
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Example: Create parsing task (upload file and parse)
|
||||||
|
*
|
||||||
|
* @param client ZaiClient instance
|
||||||
|
* @return Parsing task's taskId
|
||||||
|
*/
|
||||||
|
private static FileParsingDownloadResponse syncFileParsingTaskExample(ZaiClient client, String filePath, String fileType, String toolType) {
|
||||||
|
if (StringUtils.isEmpty(filePath)) {
|
||||||
|
System.err.println("Invalid file path.");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
FileParsingUploadReq uploadReq = FileParsingUploadReq.builder()
|
||||||
|
.filePath(filePath)
|
||||||
|
.fileType(fileType) // Supported types: pdf, docx, etc.
|
||||||
|
.toolType(toolType) // Parsing tool type: lite, prime, expert
|
||||||
|
.build();
|
||||||
|
|
||||||
|
System.out.println("Uploading file and creating parsing task...");
|
||||||
|
return client.fileParsing().syncParse(uploadReq);
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.err.println("File parsing task error: " + e.getMessage());
|
||||||
|
}
|
||||||
|
// Returning null means task creation failed
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
Loading…
Reference in a new issue