From 6c49ace41bdee70c05519d0ae2af4ec18f236fe9 Mon Sep 17 00:00:00 2001
From: Darran Zhang <lhcsdn@gmail.com>
Date: Fri, 20 Jan 2023 02:52:20 +0800
Subject: [PATCH] Add JAVA version CodeGeeX API example.

---
 api/README_zh.md                              |  40 +----
 api/codegeex-api-example-java/pom.xml         | 141 ++++++++++++++++++
 .../example/CodeGenerationExample.java        |  83 +++++++++++
 .../aminer/codegeex/example/pojo/Payload.java |  31 ++++
 .../generation_example.py                     |   0
 5 files changed, 256 insertions(+), 39 deletions(-)
 create mode 100644 api/codegeex-api-example-java/pom.xml
 create mode 100644 api/codegeex-api-example-java/src/main/java/cn/aminer/codegeex/example/CodeGenerationExample.java
 create mode 100644 api/codegeex-api-example-java/src/main/java/cn/aminer/codegeex/example/pojo/Payload.java
 rename api/{ => codegeex-api-example-python}/generation_example.py (100%)

diff --git a/api/README_zh.md b/api/README_zh.md
index 5414654..559d568 100644
--- a/api/README_zh.md
+++ b/api/README_zh.md
@@ -16,42 +16,4 @@
 在API信息中,可以查看代码生成/代码翻译的请求地址和使用文档:
 <img src="../resources/api/api_step_5.png">
 
-根据文档中的描述使用API,参考文件``api/generation_example.py``:
-
-```python
-# encoding:utf-8
-
-import requests
-import json
-
-'''
-Code Generation
-'''
-API_KEY = ""  # Get from Tianqi console. 从控制台获取
-API_SECRET = ""  # Get from Tianqi console. 从控制台获取
-PROMPT = "from typing import List\n\ndef has_close_elements(numbers: List[float], threshold: float) -> bool:\n    \"\"\" Check if in given list of numbers, are any two numbers closer to each other than\n    given threshold.\n    >>> has_close_elements([1.0, 2.0, 3.0], 0.5)\n    False\n    >>> has_close_elements([1.0, 2.8, 3.0, 4.0, 5.0, 2.0], 0.3)\n    True\n    \"\"\"\n"
-NUMBER = 3
-LANG = "Python"
-request_url = "https://tianqi.aminer.cn/api/v2/"
-api = 'multilingual_code_generate'
-
-# Request is in json format. 指定请求参数格式为json
-headers = {'Content-Type': 'application/json'}
-request_url = request_url + api
-data = {
-    "apikey": API_KEY,
-    "apisecret": API_SECRET,
-    "prompt":PROMPT,
-    "n":NUMBER,
-    "lang":LANG
-}
-
-def main():
-    response = requests.post(request_url, headers=headers, data=json.dumps(data))
-    if response:
-        print(response.json())
-
-if __name__ == '__main__':
-    main()
-```
-
+根据文档中的描述使用API,Python版参考目录``api/codegeex-api-example-python``;JAVA版参考工程:``api/codegeex-api-example-java``
diff --git a/api/codegeex-api-example-java/pom.xml b/api/codegeex-api-example-java/pom.xml
new file mode 100644
index 0000000..03d01d8
--- /dev/null
+++ b/api/codegeex-api-example-java/pom.xml
@@ -0,0 +1,141 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+
+  <groupId>cn.aminer</groupId>
+  <artifactId>codegeex-api-example-java</artifactId>
+  <version>1.0-SNAPSHOT</version>
+
+  <!--
+  如果没有下面的这段encoding配置,会导致编译的时候输出WARNING信息:
+  [WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent!
+  -->
+  <properties>
+    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
+  </properties>
+
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-compiler-plugin</artifactId>
+        <version>3.8.1</version>
+        <configuration>
+          <!-- 一般而言,target与source是保持一致的,但是,有时候为了让程序能在其他版本的jdk中运行(对于低版本目标jdk,源代码中不能使用
+          低版本jdk中不支持的语法),会存在target不同于source的情况 -->
+          <source>1.8</source><!-- 源代码使用的JDK版本 -->
+          <target>1.8</target><!-- 需要生成的目标class文件的编译版本 -->
+          <encoding>UTF-8</encoding><!-- 字符集编码 -->
+        </configuration>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-assembly-plugin</artifactId>
+        <version>3.3.0</version>
+        <configuration>
+          <descriptorRefs>
+            <descriptorRef>jar-with-dependencies</descriptorRef>
+          </descriptorRefs>
+        </configuration>
+        <!-- 有下面这段executions,才能打出包含所有dependency的fat jar -->
+        <executions>
+          <execution>
+            <phase>package</phase><!-- 指定在打包节点执行jar包合并操作 -->
+            <goals>
+              <goal>single</goal><!-- 该模块只运行一次 -->
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
+  </build>
+
+  <dependencies>
+    <dependency>
+      <groupId>com.fasterxml.jackson.module</groupId>
+      <artifactId>jackson-module-parameter-names</artifactId>
+      <version>2.6.6</version>
+    </dependency>
+    <dependency>
+      <groupId>com.fasterxml.jackson.datatype</groupId>
+      <artifactId>jackson-datatype-jdk8</artifactId>
+      <version>2.6.6</version>
+    </dependency>
+    <dependency>
+      <groupId>com.fasterxml.jackson.datatype</groupId>
+      <artifactId>jackson-datatype-jsr310</artifactId>
+      <version>2.6.6</version>
+    </dependency>
+    <dependency>
+      <groupId>com.squareup.okhttp3</groupId>
+      <artifactId>okhttp</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-log4j12</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>log4j</groupId>
+      <artifactId>log4j</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.projectlombok</groupId>
+      <artifactId>lombok</artifactId>
+      <scope>provided</scope>
+    </dependency>
+  </dependencies>
+
+  <dependencyManagement>
+    <dependencies>
+      <dependency>
+        <groupId>com.fasterxml.jackson.module</groupId>
+        <artifactId>jackson-module-parameter-names</artifactId>
+      </dependency>
+      <dependency>
+        <groupId>com.fasterxml.jackson.datatype</groupId>
+        <artifactId>jackson-datatype-jdk8</artifactId>
+      </dependency>
+      <dependency>
+        <groupId>com.fasterxml.jackson.datatype</groupId>
+        <artifactId>jackson-datatype-jsr310</artifactId>
+      </dependency>
+      <dependency>
+        <groupId>com.fasterxml.jackson.core</groupId>
+        <artifactId>jackson-databind</artifactId>
+      </dependency>
+      <dependency>
+        <groupId>com.squareup.okhttp3</groupId>
+        <artifactId>okhttp</artifactId>
+        <version>4.10.0</version>
+      </dependency>
+      <dependency>
+        <groupId>log4j</groupId>
+        <artifactId>log4j</artifactId>
+        <version>1.2.17</version>
+      </dependency>
+      <dependency>
+        <groupId>org.slf4j</groupId>
+        <artifactId>slf4j-log4j12</artifactId>
+        <version>1.7.5</version>
+      </dependency>
+      <dependency>
+        <groupId>org.projectlombok</groupId>
+        <artifactId>lombok</artifactId>
+        <version>1.18.20</version>
+        <scope>provided</scope>
+      </dependency>
+    </dependencies>
+  </dependencyManagement>
+
+  <repositories>
+    <repository>
+      <!-- Maven 自带的中央仓库使用的id为central,如果其他的仓库声明也是用该id,就会覆盖中央仓库的配置 -->
+      <id>central</id>
+      <name>ALiYun</name>
+      <url>http://maven.aliyun.com/nexus/content/groups/public</url>
+    </repository>
+  </repositories>
+</project>
diff --git a/api/codegeex-api-example-java/src/main/java/cn/aminer/codegeex/example/CodeGenerationExample.java b/api/codegeex-api-example-java/src/main/java/cn/aminer/codegeex/example/CodeGenerationExample.java
new file mode 100644
index 0000000..8a25d7a
--- /dev/null
+++ b/api/codegeex-api-example-java/src/main/java/cn/aminer/codegeex/example/CodeGenerationExample.java
@@ -0,0 +1,83 @@
+package cn.aminer.codegeex.example;
+
+import cn.aminer.codegeex.example.pojo.Payload;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import okhttp3.*;
+
+import java.io.IOException;
+
+/**
+ * 调用 CodeGeeX API 生成代码的例子。
+ *
+ * @author Darran Zhang @ codelast.com
+ * @version 2023-01-20
+ */
+public class CodeGenerationExample {
+  public static final String API_KEY = "your_api_key";  // 在"天启开放平台"上申请到的API Key
+  public static final String API_SECRET = "your_api_secret";  // 在"天启开放平台"上申请到的API Secret
+  public static final int NUMBER = 3;  // 生成几个候选
+  public static final String LANGUAGE = "Java";  // 编程语言
+  public static final String REQUEST_URL = "https://tianqi.aminer.cn/api/v2/multilingual_code_generate";  // 请求地址
+
+  public static void main(String[] args) throws Exception {
+    CodeGenerationExample example = new CodeGenerationExample();
+    String prompt = "// use OkHttpClient library to write a function to perform http post request\n\n" +
+      "public class HttpPost {\n" +
+      "    public static void main(String[] args) {\n";
+    example.generateCode(prompt);
+  }
+
+  /**
+   * 生成代码。
+   *
+   * @param prompt 待补全的代码
+   */
+  public void generateCode(String prompt) throws Exception {
+    ObjectMapper objectMapper = new ObjectMapper();
+    Payload payload = new Payload().setApiKey(API_KEY).setApiSecret(API_SECRET).setPrompt(prompt).setNumber(NUMBER)
+      .setLanguage(LANGUAGE);
+    String response = performHttpPost(REQUEST_URL, objectMapper.writeValueAsString(payload));
+    System.out.println(response);
+  }
+
+  /**
+   * 发起 HTTP POST 请求。
+   *
+   * @param url     请求的URL
+   * @param payload 请求的JSON数据
+   * @return 请求返回的内容,若出错则返回 null。
+   */
+  public String performHttpPost(String url, String payload) {
+    HttpUrl.Builder builder = null;
+    try {
+      HttpUrl httpUrl = HttpUrl.parse(url);
+      if (httpUrl != null) {
+        builder = httpUrl.newBuilder();
+      }
+    } catch (IllegalArgumentException e) {
+      System.out.println("failed to create HttpUrl.Builder from url " + url + ":" + e);
+    }
+    if (builder == null) {
+      return null;
+    }
+    OkHttpClient client = new OkHttpClient();
+    RequestBody requestBody = RequestBody.create(payload, MediaType.parse("application/json; charset=utf-8"));
+    Request request = new Request.Builder()
+      .url(builder.build())
+      .post(requestBody)
+      .build();
+
+    try {
+      Response response = client.newCall(request).execute();
+      ResponseBody body = response.body();
+      if (body == null) {
+        System.out.println("null response body");
+        return null;
+      }
+      return body.string();
+    } catch (IOException e) {
+      System.out.println("failed to send POST request: " + e);
+    }
+    return null;
+  }
+}
diff --git a/api/codegeex-api-example-java/src/main/java/cn/aminer/codegeex/example/pojo/Payload.java b/api/codegeex-api-example-java/src/main/java/cn/aminer/codegeex/example/pojo/Payload.java
new file mode 100644
index 0000000..68f088a
--- /dev/null
+++ b/api/codegeex-api-example-java/src/main/java/cn/aminer/codegeex/example/pojo/Payload.java
@@ -0,0 +1,31 @@
+package cn.aminer.codegeex.example.pojo;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+/**
+ * 发送到 CodeGeex API 的请求中包含的JSON payload对象。
+ *
+ * @author Darran Zhang @ codelast.com
+ * @version 2023-01-20
+ */
+@JsonIgnoreProperties(ignoreUnknown = true)
+@Data
+@Accessors(chain = true)
+public class Payload {
+  @JsonProperty("apikey")
+  String apiKey;  // 在"天启开放平台"上申请到的API Key
+
+  @JsonProperty("apisecret")
+  String apiSecret;  // 在"天启开放平台"上申请到的API Secret
+
+  String prompt;  // 待补全的代码
+
+  @JsonProperty("n")
+  int number;  // 生成几个候选
+
+  @JsonProperty("lang")
+  String language;  // 编程语言
+}
diff --git a/api/generation_example.py b/api/codegeex-api-example-python/generation_example.py
similarity index 100%
rename from api/generation_example.py
rename to api/codegeex-api-example-python/generation_example.py