├── .DS_Store ├── src ├── .DS_Store ├── main │ ├── .DS_Store │ └── java │ │ ├── .DS_Store │ │ └── io │ │ ├── .DS_Store │ │ └── github │ │ ├── .DS_Store │ │ └── namankhurpia │ │ ├── .DS_Store │ │ ├── Service │ │ ├── .DS_Store │ │ ├── EasyChatService.java │ │ ├── EasyopenaiAsyncService.java │ │ ├── EasyVisionService.java │ │ ├── EasyopenaiService.java │ │ ├── EasyTranscriptionService.java │ │ └── EasyopenaiConcurrentService.java │ │ ├── Interfaces │ │ ├── EndPoints.java │ │ ├── ConcurrentApiInterface.java │ │ ├── AsyncApiInterface.java │ │ ├── DaoInterface.java │ │ └── RetrofitApiInterface.java │ │ ├── Exception │ │ ├── InvalidSizeException.java │ │ └── MalformedRequestException.java │ │ ├── Pojo │ │ ├── ChatCompletion │ │ │ ├── Tools.java │ │ │ ├── ToolChoice.java │ │ │ ├── SystemMessage.java │ │ │ ├── ChatFunctionCall.java │ │ │ ├── ToolCalls.java │ │ │ ├── Function.java │ │ │ ├── ChatCompletionResponse.java │ │ │ ├── Message.java │ │ │ └── ChatCompletionRequest.java │ │ ├── Vision │ │ │ ├── FinishDetails.java │ │ │ ├── MessageList.java │ │ │ ├── ImageUrl.java │ │ │ ├── VisionApiRequest.java │ │ │ ├── Content.java │ │ │ └── VisionApiResponse.java │ │ ├── MyModels │ │ │ ├── EasyChatRequest.java │ │ │ ├── EasyVisionRequest.java │ │ │ ├── ChatCompletionRequestList.java │ │ │ ├── ModerationRequestList.java │ │ │ ├── ChatCompletionResponseList.java │ │ │ └── ModerationResponseList.java │ │ ├── Speech │ │ │ ├── SpeechRequest.java │ │ │ └── EasyTranscriptionRequest.java │ │ ├── Commons │ │ │ ├── Usage.java │ │ │ └── Choice.java │ │ ├── Moderations │ │ │ ├── Result.java │ │ │ ├── ModerationAPIResponse.java │ │ │ ├── ModerationAPIRequest.java │ │ │ ├── Categories.java │ │ │ └── CategoryScores.java │ │ ├── Image │ │ │ ├── ModelData.java │ │ │ ├── ImageResponse.java │ │ │ └── ImageRequest.java │ │ ├── Models │ │ │ ├── ModelResponse.java │ │ │ └── ModelField.java │ │ └── Completion │ │ │ ├── CompletionResponse.java │ │ │ └── CompletionRequest.java │ │ ├── DAO │ │ ├── RetrofitAPIClient.java │ │ ├── AsyncDAOImpl.java │ │ └── DAOImpl.java │ │ ├── Documentation │ │ ├── IssueSolving.java │ │ ├── RunnerForAsync.java │ │ ├── RunnerForConcurrent.java │ │ └── RunnerForSingleInstance.java │ │ └── Validators │ │ └── ParameterCheckers.java └── test │ └── java │ └── DAO │ └── DAOImplTest.java ├── .mvn ├── .DS_Store └── wrapper │ ├── maven-wrapper.jar │ └── maven-wrapper.properties ├── .github ├── ISSUE_TEMPLATE │ ├── custom.md │ ├── feature_request.md │ └── bug_report.md └── workflows │ └── maven.yml ├── .gitignore ├── LICENSE ├── CONTRIBUTING.md ├── pom.xml.versionsBackup ├── pom.xml └── README.md /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/namankhurpia/Easy-open-ai/HEAD/.DS_Store -------------------------------------------------------------------------------- /src/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/namankhurpia/Easy-open-ai/HEAD/src/.DS_Store -------------------------------------------------------------------------------- /.mvn/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/namankhurpia/Easy-open-ai/HEAD/.mvn/.DS_Store -------------------------------------------------------------------------------- /src/main/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/namankhurpia/Easy-open-ai/HEAD/src/main/.DS_Store -------------------------------------------------------------------------------- /src/main/java/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/namankhurpia/Easy-open-ai/HEAD/src/main/java/.DS_Store -------------------------------------------------------------------------------- /src/main/java/io/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/namankhurpia/Easy-open-ai/HEAD/src/main/java/io/.DS_Store -------------------------------------------------------------------------------- /.mvn/wrapper/maven-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/namankhurpia/Easy-open-ai/HEAD/.mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /src/main/java/io/github/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/namankhurpia/Easy-open-ai/HEAD/src/main/java/io/github/.DS_Store -------------------------------------------------------------------------------- /src/main/java/io/github/namankhurpia/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/namankhurpia/Easy-open-ai/HEAD/src/main/java/io/github/namankhurpia/.DS_Store -------------------------------------------------------------------------------- /src/main/java/io/github/namankhurpia/Service/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/namankhurpia/Easy-open-ai/HEAD/src/main/java/io/github/namankhurpia/Service/.DS_Store -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/custom.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Custom issue template 3 | about: Describe this issue template's purpose here. 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/main/java/io/github/namankhurpia/Interfaces/EndPoints.java: -------------------------------------------------------------------------------- 1 | package io.github.namankhurpia.Interfaces; 2 | 3 | public interface EndPoints { 4 | 5 | static final String BASE_URL = "https://api.openai.com/"; 6 | static final String OPENAI_KEY = ""; 7 | } 8 | -------------------------------------------------------------------------------- /src/main/java/io/github/namankhurpia/Exception/InvalidSizeException.java: -------------------------------------------------------------------------------- 1 | package io.github.namankhurpia.Exception; 2 | 3 | public class InvalidSizeException extends RuntimeException{ 4 | 5 | public InvalidSizeException(String errorMessage, Throwable err) { 6 | super(errorMessage, err); 7 | } 8 | 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/io/github/namankhurpia/Exception/MalformedRequestException.java: -------------------------------------------------------------------------------- 1 | package io.github.namankhurpia.Exception; 2 | 3 | public class MalformedRequestException extends RuntimeException { 4 | 5 | public MalformedRequestException(String errorMessage, Throwable err) { 6 | super(errorMessage, err); 7 | } 8 | } 9 | 10 | -------------------------------------------------------------------------------- /src/main/java/io/github/namankhurpia/Service/EasyChatService.java: -------------------------------------------------------------------------------- 1 | package io.github.namankhurpia.Service; 2 | 3 | import io.github.namankhurpia.Pojo.ChatCompletion.ChatCompletionResponse; 4 | import io.github.namankhurpia.Pojo.MyModels.EasyChatRequest; 5 | import io.github.namankhurpia.Pojo.MyModels.EasyVisionRequest; 6 | 7 | public class EasyChatService { 8 | 9 | public ChatCompletionResponse Chat(String accessToken, EasyChatRequest request) 10 | { 11 | return null; 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/io/github/namankhurpia/Pojo/ChatCompletion/Tools.java: -------------------------------------------------------------------------------- 1 | package io.github.namankhurpia.Pojo.ChatCompletion; 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty; 4 | import lombok.AllArgsConstructor; 5 | import lombok.Builder; 6 | import lombok.Data; 7 | import lombok.NoArgsConstructor; 8 | 9 | @Builder 10 | @AllArgsConstructor 11 | @NoArgsConstructor 12 | @Data 13 | public class Tools { 14 | 15 | @JsonProperty("type") 16 | String type; 17 | 18 | Function function; 19 | 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/io/github/namankhurpia/Pojo/Vision/FinishDetails.java: -------------------------------------------------------------------------------- 1 | package io.github.namankhurpia.Pojo.Vision; 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty; 4 | import com.google.gson.annotations.SerializedName; 5 | import lombok.Data; 6 | 7 | @Data 8 | public class FinishDetails { 9 | 10 | @SerializedName("type") 11 | @JsonProperty("type") 12 | public String type; 13 | 14 | @SerializedName("stop") 15 | @JsonProperty("stop") 16 | public String stop; 17 | 18 | 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/io/github/namankhurpia/Pojo/ChatCompletion/ToolChoice.java: -------------------------------------------------------------------------------- 1 | package io.github.namankhurpia.Pojo.ChatCompletion; 2 | 3 | 4 | import com.fasterxml.jackson.annotation.JsonProperty; 5 | import lombok.AllArgsConstructor; 6 | import lombok.Builder; 7 | import lombok.Data; 8 | import lombok.NoArgsConstructor; 9 | 10 | @Builder 11 | @AllArgsConstructor 12 | @NoArgsConstructor 13 | @Data 14 | public class ToolChoice { 15 | 16 | @JsonProperty("type") 17 | String type; 18 | 19 | Function function; 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/io/github/namankhurpia/Pojo/MyModels/EasyChatRequest.java: -------------------------------------------------------------------------------- 1 | package io.github.namankhurpia.Pojo.MyModels; 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty; 4 | import com.google.gson.annotations.SerializedName; 5 | 6 | import java.util.ArrayList; 7 | 8 | public class EasyChatRequest { 9 | 10 | @SerializedName("model") 11 | @JsonProperty("model") 12 | String model; 13 | 14 | @SerializedName("prompt") 15 | @JsonProperty("prompt") 16 | ArrayList prompt; 17 | 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/io/github/namankhurpia/Pojo/Vision/MessageList.java: -------------------------------------------------------------------------------- 1 | package io.github.namankhurpia.Pojo.Vision; 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty; 4 | import com.google.gson.annotations.SerializedName; 5 | import lombok.Data; 6 | 7 | import java.util.List; 8 | 9 | @Data 10 | public class MessageList { 11 | 12 | @SerializedName("role") 13 | @JsonProperty("role") 14 | public String role; 15 | 16 | @SerializedName("content") 17 | @JsonProperty("content") 18 | public List content; 19 | 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/io/github/namankhurpia/Pojo/Speech/SpeechRequest.java: -------------------------------------------------------------------------------- 1 | package io.github.namankhurpia.Pojo.Speech; 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty; 4 | import lombok.*; 5 | 6 | @Builder 7 | @AllArgsConstructor 8 | @NoArgsConstructor 9 | @Data 10 | public class SpeechRequest { 11 | 12 | @NonNull 13 | String model; 14 | 15 | @NonNull 16 | String input; 17 | 18 | @NonNull 19 | String voice; 20 | 21 | @JsonProperty("response_format") 22 | String response_format; 23 | 24 | Double speed; 25 | 26 | } 27 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | target/ 3 | !.mvn/wrapper/maven-wrapper.jar 4 | !**/src/main/**/target/ 5 | !**/src/test/**/target/ 6 | 7 | ### STS ### 8 | .apt_generated 9 | .classpath 10 | .factorypath 11 | .project 12 | .settings 13 | .springBeans 14 | .sts4-cache 15 | 16 | ### IntelliJ IDEA ### 17 | .idea 18 | *.iws 19 | *.iml 20 | *.ipr 21 | keys.txt 22 | 23 | ### NetBeans ### 24 | /nbproject/private/ 25 | /nbbuild/ 26 | /dist/ 27 | /nbdist/ 28 | /.nb-gradle/ 29 | build/ 30 | !**/src/main/**/build/ 31 | !**/src/test/**/build/ 32 | 33 | ### VS Code ### 34 | .vscode/ 35 | 36 | #my files 37 | keys.txt -------------------------------------------------------------------------------- /src/main/java/io/github/namankhurpia/Pojo/Commons/Usage.java: -------------------------------------------------------------------------------- 1 | package io.github.namankhurpia.Pojo.Commons; 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty; 4 | import lombok.Data; 5 | 6 | /** 7 | * usage 8 | * object 9 | * Usage statistics for the completion request. 10 | */ 11 | 12 | @Data 13 | public class Usage { 14 | 15 | @JsonProperty("prompt_tokens") 16 | public Integer prompt_tokens; 17 | 18 | @JsonProperty("completion_tokens") 19 | public Integer completion_tokens; 20 | 21 | @JsonProperty("total_tokens") 22 | public Integer total_tokens; 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/io/github/namankhurpia/Pojo/Vision/ImageUrl.java: -------------------------------------------------------------------------------- 1 | package io.github.namankhurpia.Pojo.Vision; 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty; 4 | import com.google.gson.annotations.SerializedName; 5 | import lombok.Data; 6 | 7 | @Data 8 | public class ImageUrl { 9 | 10 | @SerializedName("url") 11 | @JsonProperty("url") 12 | public String url; 13 | 14 | @SerializedName("detail") 15 | @JsonProperty("detail") 16 | public String detail; 17 | 18 | public ImageUrl(String url, String detail) { 19 | this.url = url; 20 | this.detail = detail; 21 | } 22 | 23 | public ImageUrl() { 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/io/github/namankhurpia/Pojo/Moderations/Result.java: -------------------------------------------------------------------------------- 1 | 2 | package io.github.namankhurpia.Pojo.Moderations; 3 | 4 | import com.fasterxml.jackson.annotation.JsonProperty; 5 | import com.fasterxml.jackson.annotation.JsonPropertyOrder; 6 | import com.google.gson.annotations.SerializedName; 7 | import lombok.Data; 8 | 9 | 10 | 11 | @Data 12 | public class Result { 13 | 14 | @JsonProperty("flagged") 15 | public Boolean flagged; 16 | 17 | @JsonProperty("categories") 18 | public Categories categories; 19 | 20 | @SerializedName("category_scores") 21 | @JsonProperty("category_scores") 22 | public CategoryScores categoryScores; 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/io/github/namankhurpia/Pojo/Image/ModelData.java: -------------------------------------------------------------------------------- 1 | package io.github.namankhurpia.Pojo.Image; 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty; 4 | import com.google.gson.annotations.SerializedName; 5 | import lombok.AllArgsConstructor; 6 | import lombok.Builder; 7 | import lombok.Data; 8 | import lombok.NoArgsConstructor; 9 | 10 | @NoArgsConstructor 11 | @AllArgsConstructor 12 | @Builder 13 | @Data 14 | public class ModelData { 15 | 16 | @JsonProperty("revised_prompt") 17 | @SerializedName("revised_prompt") 18 | public String revisedPrompt; 19 | 20 | @JsonProperty("url") 21 | @SerializedName("url") 22 | public String url; 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/io/github/namankhurpia/Pojo/Moderations/ModerationAPIResponse.java: -------------------------------------------------------------------------------- 1 | 2 | package io.github.namankhurpia.Pojo.Moderations; 3 | 4 | import com.fasterxml.jackson.annotation.JsonProperty; 5 | import com.fasterxml.jackson.annotation.JsonPropertyOrder; 6 | import com.google.gson.annotations.SerializedName; 7 | import lombok.Data; 8 | 9 | import java.util.List; 10 | 11 | 12 | 13 | @Data 14 | public class ModerationAPIResponse { 15 | 16 | @JsonProperty("id") 17 | public String id; 18 | 19 | @JsonProperty("model") 20 | public String model; 21 | 22 | @SerializedName("results") 23 | @JsonProperty("results") 24 | public List results; 25 | 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/io/github/namankhurpia/Pojo/Speech/EasyTranscriptionRequest.java: -------------------------------------------------------------------------------- 1 | package io.github.namankhurpia.Pojo.Speech; 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty; 4 | import lombok.AllArgsConstructor; 5 | import lombok.Builder; 6 | import lombok.Data; 7 | import lombok.NoArgsConstructor; 8 | 9 | @Builder 10 | @AllArgsConstructor 11 | @NoArgsConstructor 12 | @Data 13 | public class EasyTranscriptionRequest { 14 | 15 | String model; 16 | 17 | String language; 18 | 19 | String prompt; 20 | 21 | @JsonProperty("response_format") 22 | String responseFormat; 23 | 24 | Integer temperature; 25 | 26 | String filepath; 27 | 28 | 29 | 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/io/github/namankhurpia/Pojo/Vision/VisionApiRequest.java: -------------------------------------------------------------------------------- 1 | package io.github.namankhurpia.Pojo.Vision; 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty; 4 | import com.google.gson.annotations.SerializedName; 5 | import lombok.Data; 6 | 7 | import java.util.List; 8 | 9 | @Data 10 | public class VisionApiRequest { 11 | 12 | @SerializedName("model") 13 | @JsonProperty("model") 14 | public String model; 15 | 16 | @SerializedName("messages") 17 | @JsonProperty("messages") 18 | public List messages; 19 | 20 | @SerializedName("max_tokens") 21 | @JsonProperty("max_tokens") 22 | public Integer maxTokens; 23 | 24 | 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/io/github/namankhurpia/Pojo/ChatCompletion/SystemMessage.java: -------------------------------------------------------------------------------- 1 | package io.github.namankhurpia.Pojo.ChatCompletion; 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty; 4 | import lombok.*; 5 | 6 | /** 7 | * This class can be used to encapsulate System Messages and User Message and Function Message (deprecated) 8 | */ 9 | @Builder 10 | @AllArgsConstructor 11 | @NoArgsConstructor 12 | @Data 13 | public class SystemMessage { 14 | 15 | @NonNull 16 | @JsonProperty("role") 17 | public String role; 18 | 19 | 20 | @NonNull 21 | @JsonProperty("content") 22 | public String content; 23 | 24 | @JsonProperty("name") 25 | public String name; 26 | 27 | 28 | } 29 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /src/main/java/io/github/namankhurpia/Pojo/Image/ImageResponse.java: -------------------------------------------------------------------------------- 1 | package io.github.namankhurpia.Pojo.Image; 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty; 4 | import com.google.gson.annotations.SerializedName; 5 | import lombok.AllArgsConstructor; 6 | import lombok.Builder; 7 | import lombok.Data; 8 | import lombok.NoArgsConstructor; 9 | 10 | import java.util.List; 11 | 12 | @NoArgsConstructor 13 | @AllArgsConstructor 14 | @Builder 15 | @Data 16 | public class ImageResponse { 17 | 18 | @JsonProperty("created") 19 | @SerializedName("created") 20 | public Integer created; 21 | 22 | @JsonProperty("data") 23 | @SerializedName("data") 24 | public List data; 25 | 26 | 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/io/github/namankhurpia/Pojo/Models/ModelResponse.java: -------------------------------------------------------------------------------- 1 | package io.github.namankhurpia.Pojo.Models; 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty; 4 | import com.google.gson.annotations.SerializedName; 5 | import lombok.AllArgsConstructor; 6 | import lombok.Builder; 7 | import lombok.Data; 8 | import lombok.NoArgsConstructor; 9 | 10 | import java.util.List; 11 | 12 | @NoArgsConstructor 13 | @AllArgsConstructor 14 | @Builder 15 | @Data 16 | public class ModelResponse { 17 | 18 | @SerializedName("object") 19 | @JsonProperty("object") 20 | public String object; 21 | 22 | @SerializedName("data") 23 | @JsonProperty("data") 24 | public List data; 25 | 26 | 27 | } 28 | -------------------------------------------------------------------------------- /src/test/java/DAO/DAOImplTest.java: -------------------------------------------------------------------------------- 1 | package DAO; 2 | 3 | import io.github.namankhurpia.DAO.DAOImpl; 4 | import io.github.namankhurpia.DAO.RetrofitAPIClient; 5 | import io.github.namankhurpia.Exception.MalformedRequestException; 6 | import io.github.namankhurpia.Interfaces.RetrofitApiInterface; 7 | import io.github.namankhurpia.Pojo.Moderations.ModerationAPIRequest; 8 | import io.github.namankhurpia.Pojo.Moderations.ModerationAPIResponse; 9 | import org.junit.Before; 10 | import org.junit.Test; 11 | import retrofit2.Call; 12 | import retrofit2.Response; 13 | 14 | import java.io.IOException; 15 | 16 | import static org.junit.Assert.*; 17 | import static org.mockito.Mockito.*; 18 | 19 | 20 | 21 | public class DAOImplTest { 22 | 23 | 24 | 25 | 26 | 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/io/github/namankhurpia/Pojo/Vision/Content.java: -------------------------------------------------------------------------------- 1 | package io.github.namankhurpia.Pojo.Vision; 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty; 4 | import com.google.gson.annotations.SerializedName; 5 | import lombok.Data; 6 | 7 | @Data 8 | public class Content { 9 | 10 | @SerializedName("type") 11 | @JsonProperty("type") 12 | public String type; 13 | 14 | @SerializedName("text") 15 | @JsonProperty("text") 16 | public String text; 17 | 18 | @SerializedName("image_url") 19 | @JsonProperty("image_url") 20 | public ImageUrl imageUrl; 21 | 22 | public Content(String type, String text, ImageUrl imageUrl) { 23 | this.type = type; 24 | this.text = text; 25 | this.imageUrl = imageUrl; 26 | } 27 | 28 | public Content() { 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/io/github/namankhurpia/Pojo/ChatCompletion/ChatFunctionCall.java: -------------------------------------------------------------------------------- 1 | package io.github.namankhurpia.Pojo.ChatCompletion; 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty; 4 | import com.fasterxml.jackson.databind.JsonNode; 5 | import lombok.AllArgsConstructor; 6 | import lombok.Builder; 7 | import lombok.Data; 8 | import lombok.NoArgsConstructor; 9 | 10 | @Builder 11 | @AllArgsConstructor 12 | @NoArgsConstructor 13 | @Data 14 | public class ChatFunctionCall { 15 | 16 | /** 17 | * The name of the function being called 18 | */ 19 | @JsonProperty("name") 20 | String name; 21 | 22 | /** 23 | * The arguments of the call produced by the model, represented as a JsonNode for easy manipulation. 24 | */ 25 | 26 | @JsonProperty("arguments") 27 | JsonNode arguments; 28 | 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/io/github/namankhurpia/Pojo/ChatCompletion/ToolCalls.java: -------------------------------------------------------------------------------- 1 | package io.github.namankhurpia.Pojo.ChatCompletion; 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty; 4 | import lombok.AllArgsConstructor; 5 | import lombok.Builder; 6 | import lombok.Data; 7 | import lombok.NoArgsConstructor; 8 | 9 | @Builder 10 | @AllArgsConstructor 11 | @NoArgsConstructor 12 | @Data 13 | public class ToolCalls { 14 | 15 | /** 16 | * id 17 | * string 18 | * The ID of the tool call. 19 | */ 20 | @JsonProperty("id") 21 | String id; 22 | 23 | /** 24 | * type 25 | * string 26 | * The type of the tool. Currently, only function is supported. 27 | */ 28 | @JsonProperty("type") 29 | String type; 30 | 31 | @JsonProperty("function") 32 | Function function; 33 | 34 | 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/io/github/namankhurpia/Pojo/Moderations/ModerationAPIRequest.java: -------------------------------------------------------------------------------- 1 | package io.github.namankhurpia.Pojo.Moderations; 2 | 3 | import com.google.gson.annotations.SerializedName; 4 | import lombok.*; 5 | 6 | /** 7 | * This class is used to send request to OpenAI's moderation API 8 | */ 9 | @NoArgsConstructor 10 | @AllArgsConstructor 11 | @Builder 12 | @Data 13 | public class ModerationAPIRequest { 14 | 15 | /** 16 | * This input is your prompt which needs to be tested against moderations API 17 | */ 18 | @NonNull 19 | @SerializedName("input") 20 | public String input; 21 | 22 | /** 23 | * You can use two types of models as of now 24 | * 1. text-moderation-latest 25 | * 2. text-moderation-stable 26 | * 27 | */ 28 | @SerializedName("model") 29 | public String model; 30 | 31 | 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/io/github/namankhurpia/Interfaces/ConcurrentApiInterface.java: -------------------------------------------------------------------------------- 1 | package io.github.namankhurpia.Interfaces; 2 | 3 | import io.github.namankhurpia.Pojo.ChatCompletion.ChatCompletionRequest; 4 | import io.github.namankhurpia.Pojo.MyModels.ChatCompletionRequestList; 5 | import io.github.namankhurpia.Pojo.MyModels.ChatCompletionResponseList; 6 | import io.github.namankhurpia.Pojo.MyModels.ModerationRequestList; 7 | import io.github.namankhurpia.Pojo.MyModels.ModerationResponseList; 8 | 9 | import java.util.ArrayList; 10 | 11 | public interface ConcurrentApiInterface { 12 | 13 | ModerationResponseList CallMultipleModerationAPI(String key,ModerationRequestList requestList); 14 | 15 | ChatCompletionResponseList CallMultipleChatCompletionAPI(String key, ChatCompletionRequestList requestList); 16 | 17 | ChatCompletionResponseList CallMultipleChatCompletionAPI(ArrayList keyList, ChatCompletionRequestList requestList); 18 | } 19 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Desktop (please complete the following information):** 27 | - OS: [e.g. iOS] 28 | - Browser [e.g. chrome, safari] 29 | - Version [e.g. 22] 30 | 31 | **Java Version (please complete the following information):** 32 | - which java version are you using?: [e.g.JDK 18] 33 | 34 | 35 | **Additional context** 36 | Add any other context about the problem here. 37 | -------------------------------------------------------------------------------- /.github/workflows/maven.yml: -------------------------------------------------------------------------------- 1 | # This workflow will build a Java project with Maven, and cache/restore any dependencies to improve the workflow execution time 2 | # For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-java-with-maven 3 | 4 | # This workflow uses actions that are not certified by GitHub. 5 | # They are provided by a third-party and are governed by 6 | # separate terms of service, privacy policy, and support 7 | # documentation. 8 | 9 | name: Java CI with Maven 10 | 11 | on: 12 | push: 13 | branches: [ "main" ] 14 | pull_request: 15 | branches: [ "main" ] 16 | 17 | jobs: 18 | build: 19 | 20 | runs-on: ubuntu-latest 21 | 22 | steps: 23 | - uses: actions/checkout@v3 24 | - name: Set up JDK 18 25 | uses: actions/setup-java@v3 26 | with: 27 | java-version: '18' 28 | distribution: 'temurin' 29 | cache: maven 30 | - name: Build with Maven 31 | run: mvn -B package --file pom.xml 32 | 33 | -------------------------------------------------------------------------------- /src/main/java/io/github/namankhurpia/Pojo/ChatCompletion/Function.java: -------------------------------------------------------------------------------- 1 | package io.github.namankhurpia.Pojo.ChatCompletion; 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty; 4 | import lombok.AllArgsConstructor; 5 | import lombok.Builder; 6 | import lombok.Data; 7 | import lombok.NoArgsConstructor; 8 | 9 | @Builder 10 | @AllArgsConstructor 11 | @NoArgsConstructor 12 | @Data 13 | public class Function { 14 | 15 | /** 16 | * name 17 | * string 18 | * The name of the function to call. 19 | */ 20 | @JsonProperty("name") 21 | String name; 22 | 23 | @JsonProperty("description") 24 | String description; 25 | 26 | 27 | /** 28 | * The parameters the functions accepts, described as a JSON Schema object. See the guide for examples, and the JSON Schema reference for documentation about the format. 29 | * 30 | * To describe a function that accepts no parameters, provide the value {"type": "object", "properties": {}} 31 | */ 32 | @JsonProperty("parameters") 33 | Object parameters; 34 | 35 | 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/io/github/namankhurpia/Pojo/Vision/VisionApiResponse.java: -------------------------------------------------------------------------------- 1 | package io.github.namankhurpia.Pojo.Vision; 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty; 4 | import com.google.gson.annotations.SerializedName; 5 | import io.github.namankhurpia.Pojo.Commons.Choice; 6 | import io.github.namankhurpia.Pojo.Commons.Usage; 7 | import lombok.Data; 8 | 9 | import java.util.List; 10 | 11 | @Data 12 | public class VisionApiResponse { 13 | 14 | @SerializedName("id") 15 | @JsonProperty("id") 16 | public String id; 17 | 18 | @SerializedName("object") 19 | @JsonProperty("object") 20 | public String object; 21 | 22 | @SerializedName("created") 23 | @JsonProperty("created") 24 | public Integer created; 25 | 26 | @SerializedName("model") 27 | @JsonProperty("model") 28 | public String model; 29 | 30 | @SerializedName("usage") 31 | @JsonProperty("usage") 32 | public Usage usage; 33 | 34 | @SerializedName("choices") 35 | @JsonProperty("choices") 36 | public List choices; 37 | 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/io/github/namankhurpia/Pojo/ChatCompletion/ChatCompletionResponse.java: -------------------------------------------------------------------------------- 1 | package io.github.namankhurpia.Pojo.ChatCompletion; 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty; 4 | import io.github.namankhurpia.Pojo.Commons.Choice; 5 | import io.github.namankhurpia.Pojo.Commons.Usage; 6 | import lombok.AllArgsConstructor; 7 | import lombok.Builder; 8 | import lombok.Data; 9 | import lombok.NoArgsConstructor; 10 | 11 | import java.util.List; 12 | 13 | @Builder 14 | @AllArgsConstructor 15 | @NoArgsConstructor 16 | @Data 17 | public class ChatCompletionResponse { 18 | 19 | @JsonProperty("id") 20 | public String id; 21 | 22 | @JsonProperty("object") 23 | public String object; 24 | 25 | @JsonProperty("created") 26 | public Integer created; 27 | 28 | @JsonProperty("model") 29 | public String model; 30 | 31 | @JsonProperty("system_fingerprint") 32 | public String system_fingerprint; 33 | 34 | @JsonProperty("choices") 35 | public List choices; 36 | 37 | @JsonProperty("usage") 38 | public Usage usage; 39 | 40 | 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/io/github/namankhurpia/Pojo/Models/ModelField.java: -------------------------------------------------------------------------------- 1 | package io.github.namankhurpia.Pojo.Models; 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty; 4 | import com.google.gson.annotations.SerializedName; 5 | import lombok.AllArgsConstructor; 6 | import lombok.Builder; 7 | import lombok.Data; 8 | import lombok.NoArgsConstructor; 9 | 10 | @NoArgsConstructor 11 | @AllArgsConstructor 12 | @Builder 13 | @Data 14 | public class ModelField { 15 | 16 | @SerializedName("object") 17 | @JsonProperty("object") 18 | public String object; 19 | 20 | @SerializedName("id") 21 | @JsonProperty("id") 22 | public String id; 23 | 24 | @SerializedName("ready") 25 | @JsonProperty("ready") 26 | public Boolean ready; 27 | 28 | @SerializedName("owner") 29 | @JsonProperty("owner") 30 | public String owner; 31 | 32 | @SerializedName("permissions") 33 | @JsonProperty("permissions") 34 | public Object permissions; 35 | 36 | @SerializedName("created") 37 | @JsonProperty("created") 38 | public Object created; 39 | 40 | 41 | } 42 | -------------------------------------------------------------------------------- /.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # https://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.7/apache-maven-3.8.7-bin.zip 18 | wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.1/maven-wrapper-3.1.1.jar 19 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Naman Khurpia 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /src/main/java/io/github/namankhurpia/Pojo/Moderations/Categories.java: -------------------------------------------------------------------------------- 1 | 2 | package io.github.namankhurpia.Pojo.Moderations; 3 | 4 | import com.fasterxml.jackson.annotation.JsonProperty; 5 | import com.fasterxml.jackson.annotation.JsonPropertyOrder; 6 | import com.google.gson.annotations.SerializedName; 7 | import lombok.Data; 8 | 9 | 10 | 11 | 12 | @Data 13 | public class Categories { 14 | 15 | 16 | @SerializedName("harassment") 17 | public Boolean harassment; 18 | @SerializedName("self-harm") 19 | public Boolean selfHarm; 20 | @SerializedName("sexual/minors") 21 | public Boolean sexualMinors; 22 | @SerializedName("hate/threatening") 23 | public Boolean hateThreatening; 24 | @SerializedName("violence/graphic") 25 | public Boolean violenceGraphic; 26 | @SerializedName("self-harm/intent") 27 | public Boolean selfHarmIntent; 28 | @SerializedName("self-harm/instructions") 29 | public Boolean selfHarmInstructions; 30 | @SerializedName("harassment/threatening") 31 | public Boolean harassmentThreatening; 32 | @SerializedName("violence") 33 | public Boolean violence; 34 | 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/io/github/namankhurpia/DAO/RetrofitAPIClient.java: -------------------------------------------------------------------------------- 1 | package io.github.namankhurpia.DAO; 2 | 3 | import okhttp3.OkHttpClient; 4 | import retrofit2.Retrofit; 5 | import retrofit2.converter.gson.GsonConverterFactory; 6 | 7 | import java.util.concurrent.TimeUnit; 8 | 9 | import static io.github.namankhurpia.Interfaces.EndPoints.BASE_URL; 10 | 11 | public class RetrofitAPIClient { 12 | 13 | private static Retrofit retrofit = null; 14 | 15 | public static Retrofit getClient(){ 16 | 17 | //for adding Http logging 18 | //HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(); 19 | //interceptor.setLevel(HttpLoggingInterceptor.Level.BODY); 20 | //OkHttpClient client = new OkHttpClient.Builder().setReadTimeout$okhttp(600).build(); 21 | 22 | final OkHttpClient client= new OkHttpClient.Builder() 23 | .readTimeout(60, TimeUnit.SECONDS) 24 | .connectTimeout(60, TimeUnit.SECONDS) 25 | .build(); 26 | 27 | 28 | retrofit =new Retrofit.Builder() 29 | .baseUrl(BASE_URL) 30 | .addConverterFactory(GsonConverterFactory.create()) 31 | .client(client) 32 | .build(); 33 | 34 | return retrofit; 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/io/github/namankhurpia/Pojo/Image/ImageRequest.java: -------------------------------------------------------------------------------- 1 | package io.github.namankhurpia.Pojo.Image; 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty; 4 | import com.google.gson.annotations.SerializedName; 5 | import lombok.*; 6 | 7 | @NoArgsConstructor 8 | @AllArgsConstructor 9 | @Builder 10 | @Data 11 | public class ImageRequest { 12 | 13 | /** 14 | * This input is your prompt which needs to be tested against moderations API 15 | */ 16 | @NonNull 17 | @JsonProperty("prompt") 18 | @SerializedName("prompt") 19 | public String prompt; 20 | 21 | /** 22 | * Defaults to dall-e-2 23 | * dall-e-3 24 | * 25 | */ 26 | @JsonProperty("model") 27 | @SerializedName("model") 28 | public String model; 29 | 30 | @JsonProperty("n") 31 | @SerializedName("n") 32 | Integer n; 33 | 34 | @JsonProperty("quality") 35 | @SerializedName("quality") 36 | String quality; 37 | 38 | @JsonProperty("response_format") 39 | @SerializedName("response_format") 40 | String response_format; 41 | 42 | @JsonProperty("size") 43 | @SerializedName("size") 44 | String size; 45 | 46 | @JsonProperty("style") 47 | @SerializedName("style") 48 | String style; 49 | 50 | @JsonProperty("user") 51 | @SerializedName("user") 52 | String user; 53 | 54 | } 55 | -------------------------------------------------------------------------------- /src/main/java/io/github/namankhurpia/Pojo/Moderations/CategoryScores.java: -------------------------------------------------------------------------------- 1 | 2 | package io.github.namankhurpia.Pojo.Moderations; 3 | 4 | import com.fasterxml.jackson.annotation.JsonInclude; 5 | import com.fasterxml.jackson.annotation.JsonProperty; 6 | import com.fasterxml.jackson.annotation.JsonPropertyOrder; 7 | import com.google.gson.annotations.SerializedName; 8 | import lombok.Data; 9 | 10 | @JsonInclude(JsonInclude.Include.NON_NULL) 11 | 12 | @Data 13 | public class CategoryScores { 14 | 15 | @SerializedName("sexual") 16 | public Double sexual; 17 | 18 | @SerializedName("hate") 19 | public Double hate; 20 | 21 | @SerializedName("harassment") 22 | public Double harassment; 23 | 24 | @SerializedName("self-harm") 25 | public Double selfHarm; 26 | 27 | @SerializedName("sexual/minors") 28 | public Double sexualMinors; 29 | 30 | @SerializedName("hate/threatening") 31 | public Double hateThreatening; 32 | 33 | @SerializedName("violence/graphic") 34 | public Double violenceGraphic; 35 | 36 | @SerializedName("self-harm/intent") 37 | public Double selfHarmIntent; 38 | 39 | @SerializedName("self-harm/instructions") 40 | public Double selfHarmInstructions; 41 | 42 | @SerializedName("harassment/threatening") 43 | public Double harassmentThreatening; 44 | 45 | @SerializedName("violence") 46 | public Double violence; 47 | 48 | 49 | 50 | } 51 | -------------------------------------------------------------------------------- /src/main/java/io/github/namankhurpia/Interfaces/AsyncApiInterface.java: -------------------------------------------------------------------------------- 1 | package io.github.namankhurpia.Interfaces; 2 | 3 | import io.github.namankhurpia.Pojo.ChatCompletion.ChatCompletionRequest; 4 | import io.github.namankhurpia.Pojo.ChatCompletion.ChatCompletionResponse; 5 | import io.github.namankhurpia.Pojo.Moderations.ModerationAPIRequest; 6 | import io.github.namankhurpia.Pojo.Moderations.ModerationAPIResponse; 7 | import io.github.namankhurpia.Pojo.Vision.VisionApiRequest; 8 | import io.github.namankhurpia.Pojo.Vision.VisionApiResponse; 9 | import retrofit2.Call; 10 | import retrofit2.http.Body; 11 | import retrofit2.http.Header; 12 | import retrofit2.http.POST; 13 | 14 | import java.io.IOException; 15 | import java.util.concurrent.ExecutionException; 16 | 17 | public interface AsyncApiInterface { 18 | 19 | //Moderation API to classify the input text 20 | ModerationAPIResponse getASyncModeration(@Header("Authorization")String accessToken, @Body ModerationAPIRequest request) throws IOException, ExecutionException, InterruptedException; 21 | 22 | ChatCompletionResponse getAsyncChatCompletion(@Header("Authorization")String accessToken, @Body ChatCompletionRequest request)throws IOException, ExecutionException, InterruptedException; 23 | 24 | VisionApiResponse getAsyncVisionAPI(@Header("Authorization")String accessToken, @Body VisionApiRequest request)throws IOException, ExecutionException, InterruptedException; 25 | 26 | 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/io/github/namankhurpia/Pojo/Commons/Choice.java: -------------------------------------------------------------------------------- 1 | package io.github.namankhurpia.Pojo.Commons; 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty; 4 | import com.google.gson.annotations.SerializedName; 5 | import io.github.namankhurpia.Pojo.ChatCompletion.SystemMessage; 6 | import io.github.namankhurpia.Pojo.Vision.FinishDetails; 7 | import lombok.Data; 8 | 9 | 10 | /** 11 | * The reason the model stopped generating tokens. 12 | * This will be stop if the model hit a natural stop point or a provided stop sequence, length if the 13 | * maximum number of tokens specified in the request was reached, or content_filter if 14 | * content was omitted due to a flag from our content filters. 15 | */ 16 | @Data 17 | public class Choice { 18 | 19 | @SerializedName("text") 20 | @JsonProperty("text") 21 | public String text; 22 | 23 | @SerializedName("index") 24 | @JsonProperty("index") 25 | public Integer index; 26 | 27 | @SerializedName("logprobs") 28 | @JsonProperty("logprobs") 29 | public Object logprobs; 30 | 31 | @SerializedName("message") 32 | @JsonProperty("message") 33 | public SystemMessage systemMessage; 34 | 35 | @SerializedName("finish_reason") 36 | @JsonProperty("finish_reason") 37 | public String finish_reason; 38 | 39 | @SerializedName("finish_details") 40 | @JsonProperty("finish_details") 41 | public FinishDetails finishDetails; 42 | 43 | 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/io/github/namankhurpia/Pojo/ChatCompletion/Message.java: -------------------------------------------------------------------------------- 1 | package io.github.namankhurpia.Pojo.ChatCompletion; 2 | 3 | import com.fasterxml.jackson.annotation.JsonInclude; 4 | import com.fasterxml.jackson.annotation.JsonProperty; 5 | import lombok.*; 6 | 7 | import java.util.List; 8 | 9 | 10 | /** 11 | * This class encapsulates - System Message, User Message, Assistant Message, Tool Message, Function Message 12 | * Refer - https://platform.openai.com/docs/api-reference/chat/create 13 | */ 14 | @Builder 15 | @AllArgsConstructor 16 | @NoArgsConstructor 17 | @Data 18 | public class Message { 19 | 20 | @NonNull 21 | String role; 22 | 23 | @NonNull 24 | @JsonInclude() // content should always exist in the call, even if it is null 25 | String content; 26 | //name is optional, The name of the author of this message. May contain a-z, A-Z, 0-9, and underscores, with a maximum length of 64 characters. 27 | String name; 28 | 29 | @JsonProperty("tool_calls") 30 | List tool_calls; 31 | 32 | @JsonProperty("function_call") 33 | ChatFunctionCall function_call; 34 | 35 | @JsonProperty("tool_call_id") 36 | String tool_call_id; 37 | 38 | public Message(String role, String content) { 39 | this.role = role; 40 | this.content = content; 41 | } 42 | 43 | public Message(String role, String content, String name) { 44 | this.role = role; 45 | this.content = content; 46 | this.name = name; 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/io/github/namankhurpia/Pojo/Completion/CompletionResponse.java: -------------------------------------------------------------------------------- 1 | package io.github.namankhurpia.Pojo.Completion; 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty; 4 | import io.github.namankhurpia.Pojo.Commons.Choice; 5 | import io.github.namankhurpia.Pojo.Commons.Usage; 6 | import lombok.Data; 7 | 8 | import java.util.List; 9 | 10 | @Data 11 | public class CompletionResponse { 12 | 13 | /** 14 | * id 15 | * string 16 | * A unique identifier for the completion. 17 | */ 18 | @JsonProperty("id") 19 | public String id; 20 | 21 | /** 22 | * string 23 | * The object type, which is always "text_completion" 24 | */ 25 | @JsonProperty("object") 26 | public String object; 27 | 28 | /** 29 | * The Unix timestamp (in seconds) of when the completion was created. 30 | */ 31 | @JsonProperty("created") 32 | public Integer created; 33 | 34 | /** 35 | * The model used for completion. 36 | */ 37 | @JsonProperty("model") 38 | public String model; 39 | 40 | /** 41 | * choices 42 | * array 43 | * The list of completion choices the model generated for the input prompt. 44 | */ 45 | @JsonProperty("choices") 46 | public List choices; 47 | 48 | 49 | 50 | @JsonProperty("usage") 51 | public Usage usage; 52 | 53 | @JsonProperty("system_fingerprint") 54 | public Usage systemFingerprint; 55 | 56 | public CompletionResponse( ) { 57 | 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # How to Contribute 2 | 3 | ## How to Add a New API 4 | 5 | ### Add POJOs to API library 6 | I have manually read all documentation given by OpenAI and then decided to make the models. 7 | 8 | - Make all java variables camel case, and use `@JsonProperty` for fields that OpenAI returns as snake case 9 | - Include comments for each variable, I take these directly from the OpenAI website 10 | - Include `@Builder @NoArgsConstructor @AllArgsConstructor @Data` on every request/response/model class. 11 | - The flow of the Application goes like - Documentation/RunnerForSingleInstance.java -> Service/EasyopenaiService.java -> DAO/DAOImpl.java -> OPENAI's server 12 | - Add as many checks as you can to validate all mandatory parameters, saving all network requests. 13 | 14 | ### Add an Integration Test 15 | Since 99% of the work of this library is done on OpenAI's servers, the objective of these tests is to call each endpoint at least once. 16 | Specify every available parameter to make sure that OpenAI accepts everything, but don't create extra test cases unless a parameter drastically affects the results. 17 | 18 | I request you to please check the file [RunnerForSingleInstance](https://github.com/namankhurpia/Easy-open-ai/blob/main/src/main/java/io/github/namankhurpia/Documentation/RunnerForSingleInstance.java) for single threaded response. Please test the function you added/changed, Make a proper call using real key. 19 | 20 | Similarly for Concurrent - [RunnerForConcurrent](https://github.com/namankhurpia/Easy-open-ai/blob/main/src/main/java/io/github/namankhurpia/Documentation/RunnerForConcurrent.java) and [RunnerForAsync](https://github.com/namankhurpia/Easy-open-ai/blob/main/src/main/java/io/github/namankhurpia/Documentation/RunnerForAsync.java) for Asynchronous Multithreaded Tasks. -------------------------------------------------------------------------------- /src/main/java/io/github/namankhurpia/Service/EasyopenaiAsyncService.java: -------------------------------------------------------------------------------- 1 | package io.github.namankhurpia.Service; 2 | 3 | import io.github.namankhurpia.DAO.AsyncDAOImpl; 4 | import io.github.namankhurpia.Interfaces.AsyncApiInterface; 5 | import io.github.namankhurpia.Pojo.ChatCompletion.ChatCompletionRequest; 6 | import io.github.namankhurpia.Pojo.ChatCompletion.ChatCompletionResponse; 7 | import io.github.namankhurpia.Pojo.Moderations.ModerationAPIRequest; 8 | import io.github.namankhurpia.Pojo.Moderations.ModerationAPIResponse; 9 | import io.github.namankhurpia.Pojo.Vision.VisionApiRequest; 10 | import io.github.namankhurpia.Pojo.Vision.VisionApiResponse; 11 | 12 | import java.io.IOException; 13 | import java.util.concurrent.ExecutionException; 14 | 15 | public class EasyopenaiAsyncService implements AsyncApiInterface { 16 | 17 | private AsyncDAOImpl asyncdao; 18 | 19 | public EasyopenaiAsyncService(AsyncDAOImpl asyncdao) { 20 | this.asyncdao = asyncdao; 21 | } 22 | 23 | @Override 24 | public ModerationAPIResponse getASyncModeration(String accessToken, ModerationAPIRequest request) throws IOException, ExecutionException, InterruptedException { 25 | return asyncdao.getASyncModeration(accessToken,request); 26 | 27 | } 28 | 29 | @Override 30 | public ChatCompletionResponse getAsyncChatCompletion(String accessToken, ChatCompletionRequest request) throws IOException, ExecutionException, InterruptedException { 31 | return asyncdao.getAsyncChatCompletion(accessToken,request); 32 | } 33 | 34 | @Override 35 | public VisionApiResponse getAsyncVisionAPI(String accessToken, VisionApiRequest request) throws IOException, ExecutionException, InterruptedException { 36 | return asyncdao.getAsyncVisionAPI(accessToken,request); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/io/github/namankhurpia/Pojo/MyModels/EasyVisionRequest.java: -------------------------------------------------------------------------------- 1 | package io.github.namankhurpia.Pojo.MyModels; 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty; 4 | import com.google.gson.annotations.SerializedName; 5 | import lombok.AllArgsConstructor; 6 | import lombok.Builder; 7 | import lombok.Data; 8 | import lombok.NoArgsConstructor; 9 | 10 | import java.util.ArrayList; 11 | 12 | @Builder 13 | @AllArgsConstructor 14 | @NoArgsConstructor 15 | @Data 16 | public class EasyVisionRequest { 17 | 18 | @SerializedName("model") 19 | @JsonProperty("model") 20 | String model; 21 | 22 | @SerializedName("imageUrls") 23 | @JsonProperty("imageUrls") 24 | ArrayList imageUrls; 25 | 26 | @SerializedName("prompt") 27 | @JsonProperty("prompt") 28 | String prompt; 29 | 30 | /** 31 | * optional - defaults to 300 32 | */ 33 | @SerializedName("maxtokens") 34 | @JsonProperty("maxtokens") 35 | Integer maxtokens; 36 | 37 | public String getModel() { 38 | return model; 39 | } 40 | 41 | public EasyVisionRequest setModel(String model) { 42 | this.model = model; 43 | return this; 44 | } 45 | 46 | public ArrayList getImageUrls() { 47 | return imageUrls; 48 | } 49 | 50 | public EasyVisionRequest setImageUrls(ArrayList imageUrls) { 51 | this.imageUrls = imageUrls; 52 | return this; 53 | } 54 | 55 | public String getPrompt() { 56 | return prompt; 57 | } 58 | 59 | public EasyVisionRequest setPrompt(String prompt) { 60 | this.prompt = prompt; 61 | return this; 62 | } 63 | 64 | public Integer getMaxtokens() { 65 | return maxtokens; 66 | } 67 | 68 | public EasyVisionRequest setMaxtokens(Integer maxtokens) { 69 | this.maxtokens = maxtokens; 70 | return this; 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/main/java/io/github/namankhurpia/Service/EasyVisionService.java: -------------------------------------------------------------------------------- 1 | package io.github.namankhurpia.Service; 2 | 3 | import io.github.namankhurpia.DAO.DAOImpl; 4 | import io.github.namankhurpia.Pojo.MyModels.EasyVisionRequest; 5 | import io.github.namankhurpia.Pojo.Vision.*; 6 | 7 | import java.io.IOException; 8 | import java.util.ArrayList; 9 | 10 | public class EasyVisionService { 11 | 12 | public VisionApiResponse VisionAPI(String accessToken, EasyVisionRequest request) throws IOException { 13 | 14 | VisionApiRequest originalVisionRequest = new VisionApiRequest(); 15 | ArrayList listofContent = new ArrayList<>(); 16 | 17 | Content content_prompt = new Content(); 18 | content_prompt.setText(request.getPrompt()); 19 | content_prompt.setType("text"); 20 | listofContent.add(content_prompt); 21 | 22 | Content temp; 23 | int n = request.getImageUrls().size(); 24 | for(int i=0;i listofMessage= new ArrayList<>(); 37 | listofMessage.add(messageList); 38 | 39 | originalVisionRequest.setModel(request.getModel()); 40 | originalVisionRequest.setMessages(listofMessage); 41 | 42 | if(request.getMaxtokens()==null ||request.getMaxtokens()==0 ) 43 | { 44 | originalVisionRequest.setMaxTokens(300); 45 | } 46 | 47 | EasyopenaiService obj = new EasyopenaiService(new DAOImpl()); 48 | VisionApiResponse res = obj.visionAPI(accessToken,originalVisionRequest); 49 | 50 | return res; 51 | 52 | 53 | } 54 | 55 | } 56 | -------------------------------------------------------------------------------- /src/main/java/io/github/namankhurpia/Pojo/MyModels/ChatCompletionRequestList.java: -------------------------------------------------------------------------------- 1 | package io.github.namankhurpia.Pojo.MyModels; 2 | 3 | import io.github.namankhurpia.Pojo.ChatCompletion.ChatCompletionRequest; 4 | import lombok.AllArgsConstructor; 5 | import lombok.Builder; 6 | import lombok.Data; 7 | import lombok.NoArgsConstructor; 8 | 9 | 10 | import java.util.ArrayList; 11 | import java.util.Collection; 12 | 13 | /** 14 | * contains all functionality of an arraylist 15 | */ 16 | @Builder 17 | @AllArgsConstructor 18 | @NoArgsConstructor 19 | @Data 20 | public class ChatCompletionRequestList { 21 | 22 | /** 23 | * Min Size = 1; 24 | */ 25 | 26 | ArrayList requestList; 27 | 28 | 29 | public void add(ChatCompletionRequest obj) 30 | { 31 | requestList.add(obj); 32 | } 33 | 34 | public void remove(int index) 35 | { 36 | requestList.remove(index); 37 | } 38 | 39 | public void remove(ChatCompletionRequest obj) 40 | { 41 | requestList.remove(obj); 42 | } 43 | 44 | public int size() 45 | { 46 | return requestList.size(); 47 | } 48 | 49 | public void add(int index, ChatCompletionRequest element) 50 | { 51 | requestList.add(index, element); 52 | } 53 | 54 | public void addAll(Collection collection) 55 | { 56 | requestList.addAll(collection); 57 | } 58 | 59 | public void addAll(int index,Collection collection) 60 | { 61 | requestList.addAll(index,collection); 62 | } 63 | 64 | public void clear() 65 | { 66 | requestList.clear(); 67 | } 68 | 69 | public boolean contains(ChatCompletionRequest request) 70 | { 71 | return requestList.contains(request); 72 | } 73 | 74 | public ChatCompletionRequest get(int index) 75 | { 76 | return requestList.get(index); 77 | } 78 | 79 | public int indexOf(ChatCompletionRequest obj) 80 | { 81 | return requestList.indexOf(obj); 82 | } 83 | 84 | public boolean isEmpty() 85 | { 86 | return requestList.isEmpty(); 87 | } 88 | 89 | 90 | 91 | } 92 | -------------------------------------------------------------------------------- /src/main/java/io/github/namankhurpia/Pojo/MyModels/ModerationRequestList.java: -------------------------------------------------------------------------------- 1 | package io.github.namankhurpia.Pojo.MyModels; 2 | 3 | import io.github.namankhurpia.Pojo.Moderations.ModerationAPIRequest; 4 | import lombok.AllArgsConstructor; 5 | import lombok.Builder; 6 | import lombok.Data; 7 | import lombok.NoArgsConstructor; 8 | 9 | import java.util.ArrayList; 10 | import java.util.Collection; 11 | 12 | /** 13 | * contains all functionality of an arraylist 14 | */ 15 | @Builder 16 | @AllArgsConstructor 17 | @NoArgsConstructor 18 | @Data 19 | public class ModerationRequestList { 20 | 21 | /** 22 | * Min Size = 1; 23 | */ 24 | 25 | ArrayList requestList; 26 | 27 | public void add(ModerationAPIRequest obj) 28 | { 29 | requestList.add(obj); 30 | } 31 | 32 | public void remove(int index) 33 | { 34 | requestList.remove(index); 35 | } 36 | 37 | public void remove(ModerationAPIRequest obj) 38 | { 39 | requestList.remove(obj); 40 | } 41 | 42 | public int size() 43 | { 44 | return requestList.size(); 45 | } 46 | 47 | public void add(int index, ModerationAPIRequest element) 48 | { 49 | requestList.add(index, element); 50 | } 51 | 52 | public void addAll(Collection collection) 53 | { 54 | requestList.addAll(collection); 55 | } 56 | 57 | public void addAll(int index,Collection collection) 58 | { 59 | requestList.addAll(index,collection); 60 | } 61 | 62 | public void clear() 63 | { 64 | requestList.clear(); 65 | } 66 | 67 | public boolean contains(ModerationAPIRequest request) 68 | { 69 | return requestList.contains(request); 70 | } 71 | 72 | public ModerationAPIRequest get(int index) 73 | { 74 | return requestList.get(index); 75 | } 76 | 77 | public int indexOf(ModerationAPIRequest obj) 78 | { 79 | return requestList.indexOf(obj); 80 | } 81 | 82 | public boolean isEmpty() 83 | { 84 | return requestList.isEmpty(); 85 | } 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | } 95 | -------------------------------------------------------------------------------- /src/main/java/io/github/namankhurpia/Pojo/MyModels/ChatCompletionResponseList.java: -------------------------------------------------------------------------------- 1 | package io.github.namankhurpia.Pojo.MyModels; 2 | 3 | 4 | import io.github.namankhurpia.Pojo.ChatCompletion.ChatCompletionResponse; 5 | import lombok.AllArgsConstructor; 6 | import lombok.Builder; 7 | import lombok.Data; 8 | import lombok.NoArgsConstructor; 9 | import retrofit2.http.Body; 10 | 11 | 12 | import java.util.ArrayList; 13 | import java.util.Collection; 14 | 15 | /** 16 | * contains all functionality of an arraylist 17 | */ 18 | @Builder 19 | @AllArgsConstructor 20 | @NoArgsConstructor 21 | @Data 22 | public class ChatCompletionResponseList { 23 | 24 | /** 25 | * Min Size = 1; 26 | */ 27 | ArrayList responseList; 28 | 29 | 30 | public void add(ChatCompletionResponse obj) 31 | { 32 | responseList.add(obj); 33 | } 34 | 35 | public void remove(int index) 36 | { 37 | responseList.remove(index); 38 | } 39 | 40 | public void remove(ChatCompletionResponse obj) 41 | { 42 | responseList.remove(obj); 43 | } 44 | 45 | public int size() 46 | { 47 | return responseList.size(); 48 | } 49 | 50 | public void add(int index, ChatCompletionResponse element) 51 | { 52 | responseList.add(index, element); 53 | } 54 | 55 | public void addAll(Collection collection) 56 | { 57 | responseList.addAll(collection); 58 | } 59 | 60 | public void addAll(int index,Collection collection) 61 | { 62 | responseList.addAll(index,collection); 63 | } 64 | 65 | public void clear() 66 | { 67 | responseList.clear(); 68 | } 69 | 70 | public boolean contains(ChatCompletionResponse request) 71 | { 72 | return responseList.contains(request); 73 | } 74 | 75 | public ChatCompletionResponse get(int index) 76 | { 77 | return responseList.get(index); 78 | } 79 | 80 | public int indexOf(ChatCompletionResponse obj) 81 | { 82 | return responseList.indexOf(obj); 83 | } 84 | 85 | public boolean isEmpty() 86 | { 87 | return responseList.isEmpty(); 88 | } 89 | 90 | } 91 | -------------------------------------------------------------------------------- /src/main/java/io/github/namankhurpia/Pojo/MyModels/ModerationResponseList.java: -------------------------------------------------------------------------------- 1 | package io.github.namankhurpia.Pojo.MyModels; 2 | 3 | import io.github.namankhurpia.Pojo.Moderations.ModerationAPIRequest; 4 | import io.github.namankhurpia.Pojo.Moderations.ModerationAPIResponse; 5 | import lombok.AllArgsConstructor; 6 | import lombok.Builder; 7 | import lombok.Data; 8 | import lombok.NoArgsConstructor; 9 | 10 | import java.util.ArrayList; 11 | import java.util.Collection; 12 | 13 | /** 14 | * contains all functionality of an arraylist 15 | */ 16 | @Builder 17 | @AllArgsConstructor 18 | @NoArgsConstructor 19 | @Data 20 | public class ModerationResponseList { 21 | 22 | /** 23 | * Min Size = 1; 24 | */ 25 | ArrayList responseList; 26 | 27 | public void add(ModerationAPIResponse obj) 28 | { 29 | responseList.add(obj); 30 | } 31 | 32 | public void remove(int index) 33 | { 34 | responseList.remove(index); 35 | } 36 | 37 | public void remove(ModerationAPIResponse obj) 38 | { 39 | responseList.remove(obj); 40 | } 41 | 42 | public int size() 43 | { 44 | return responseList.size(); 45 | } 46 | 47 | public void add(int index, ModerationAPIResponse element) 48 | { 49 | responseList.add(index, element); 50 | } 51 | 52 | public void addAll(Collection collection) 53 | { 54 | responseList.addAll(collection); 55 | } 56 | 57 | public void addAll(int index,Collection collection) 58 | { 59 | responseList.addAll(index,collection); 60 | } 61 | 62 | public void clear() 63 | { 64 | responseList.clear(); 65 | } 66 | 67 | public boolean contains(ModerationAPIResponse request) 68 | { 69 | return responseList.contains(request); 70 | } 71 | 72 | public ModerationAPIResponse get(int index) 73 | { 74 | return responseList.get(index); 75 | } 76 | 77 | public int indexOf(ModerationAPIResponse obj) 78 | { 79 | return responseList.indexOf(obj); 80 | } 81 | 82 | public boolean isEmpty() 83 | { 84 | return responseList.isEmpty(); 85 | } 86 | 87 | 88 | } 89 | -------------------------------------------------------------------------------- /src/main/java/io/github/namankhurpia/Documentation/IssueSolving.java: -------------------------------------------------------------------------------- 1 | package io.github.namankhurpia.Documentation; 2 | 3 | import io.github.namankhurpia.DAO.DAOImpl; 4 | import io.github.namankhurpia.Pojo.ChatCompletion.ChatCompletionRequest; 5 | import io.github.namankhurpia.Pojo.ChatCompletion.ChatCompletionResponse; 6 | import io.github.namankhurpia.Pojo.ChatCompletion.Message; 7 | import io.github.namankhurpia.Service.EasyopenaiService; 8 | 9 | import java.io.File; 10 | import java.io.FileNotFoundException; 11 | import java.io.IOException; 12 | import java.util.ArrayList; 13 | import java.util.List; 14 | import java.util.Scanner; 15 | 16 | public class IssueSolving { 17 | 18 | public static void main(String[] args) throws IOException { 19 | 20 | usingTopp(); 21 | } 22 | 23 | public static void usingTopp() throws IOException { 24 | ArrayList keys = readKeys(); 25 | Message message = Message.builder() 26 | .role("user") 27 | .content("what is the capital of Cambodia?") 28 | .build(); 29 | 30 | List messages = new ArrayList<>(); 31 | messages.add(message); 32 | 33 | ChatCompletionRequest request = ChatCompletionRequest.builder() 34 | .model("gpt-3.5-turbo") 35 | .messages(messages) 36 | .temperature(1.0d) 37 | .topP(1.0d) 38 | .build(); 39 | 40 | ChatCompletionResponse response = new EasyopenaiService(new DAOImpl()).chatCompletion(keys.get(0),request); 41 | System.out.println(response); 42 | 43 | } 44 | 45 | public static ArrayList readKeys() 46 | { 47 | String filePath = "keys.txt"; 48 | ArrayList keyList = new ArrayList<>(); 49 | 50 | // Open the file using Scanner 51 | try { 52 | File file = new File(filePath); 53 | Scanner scanner = new Scanner(file); 54 | 55 | // Read each line and extract keys 56 | while (scanner.hasNextLine()) { 57 | String line = scanner.nextLine(); 58 | // Assuming each line contains a key 59 | keyList.add(line); 60 | //System.out.println("Key: " + line); 61 | } 62 | 63 | // Close the scanner 64 | scanner.close(); 65 | } catch (FileNotFoundException e) { 66 | System.out.println("File not found: " + filePath); 67 | e.printStackTrace(); 68 | } 69 | return keyList; 70 | } 71 | 72 | } 73 | -------------------------------------------------------------------------------- /src/main/java/io/github/namankhurpia/Interfaces/DaoInterface.java: -------------------------------------------------------------------------------- 1 | package io.github.namankhurpia.Interfaces; 2 | 3 | import io.github.namankhurpia.Pojo.ChatCompletion.ChatCompletionRequest; 4 | import io.github.namankhurpia.Pojo.ChatCompletion.ChatCompletionResponse; 5 | import io.github.namankhurpia.Pojo.Completion.CompletionRequest; 6 | import io.github.namankhurpia.Pojo.Completion.CompletionResponse; 7 | import io.github.namankhurpia.Pojo.Image.ImageRequest; 8 | import io.github.namankhurpia.Pojo.Image.ImageResponse; 9 | import io.github.namankhurpia.Pojo.Models.ModelResponse; 10 | import io.github.namankhurpia.Pojo.Moderations.ModerationAPIRequest; 11 | import io.github.namankhurpia.Pojo.Moderations.ModerationAPIResponse; 12 | import io.github.namankhurpia.Pojo.Speech.SpeechRequest; 13 | import io.github.namankhurpia.Pojo.Vision.VisionApiRequest; 14 | import io.github.namankhurpia.Pojo.Vision.VisionApiResponse; 15 | import okhttp3.MultipartBody; 16 | import okhttp3.RequestBody; 17 | import okhttp3.ResponseBody; 18 | import retrofit2.Call; 19 | import retrofit2.http.Body; 20 | import retrofit2.http.Header; 21 | import retrofit2.http.POST; 22 | import retrofit2.http.Part; 23 | 24 | import java.io.IOException; 25 | 26 | public interface DaoInterface { 27 | 28 | //input and model are mandatory fields 29 | ModerationAPIResponse getmoderation(@Header("Authorization")String accessToken, @Body ModerationAPIRequest request) throws IOException; 30 | 31 | //model and prompt are mandatory fields 32 | CompletionResponse getCompletion(@Header("Authorization")String accessToken, @Body CompletionRequest request) throws IOException; 33 | 34 | //model , message (role and content) are mandatory fields 35 | ChatCompletionResponse chatCompletion(@Header("Authorization") String accessToken, @Body ChatCompletionRequest request) throws IOException; 36 | 37 | VisionApiResponse visionAPI(@Header("Authorization")String accessToken, @Body VisionApiRequest request)throws IOException; 38 | 39 | ResponseBody createSpeech(@Header("Authorization")String accessToken, @Body SpeechRequest request) throws IOException; 40 | 41 | ResponseBody createTranscriptions(@Header("Authorization")String accessToken, @Part MultipartBody.Part file, @Part RequestBody model, @Part RequestBody language, @Part RequestBody prompt, @Part RequestBody response_format, @Part RequestBody temperature ) throws IOException; 42 | 43 | ImageResponse createImage(@Header("Authorization")String accessToken, ImageRequest imageRequest) throws IOException; 44 | 45 | ModelResponse getAllModels(@Header("Authorization")String accessToken)throws IOException; 46 | 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/io/github/namankhurpia/Validators/ParameterCheckers.java: -------------------------------------------------------------------------------- 1 | package io.github.namankhurpia.Validators; 2 | 3 | import io.github.namankhurpia.Pojo.ChatCompletion.Message; 4 | import io.github.namankhurpia.Pojo.ChatCompletion.ChatCompletionRequest; 5 | import io.github.namankhurpia.Pojo.Completion.CompletionRequest; 6 | import io.github.namankhurpia.Pojo.Moderations.ModerationAPIRequest; 7 | import org.apache.commons.lang3.StringUtils; 8 | 9 | 10 | import java.util.List; 11 | 12 | /** 13 | * This class contains static methods to check any obvious inconsistencies in request. (Mandatory field checks) 14 | */ 15 | public class ParameterCheckers { 16 | 17 | /** 18 | * input and model are mandatory fields 19 | */ 20 | 21 | public static boolean checkParamForModeration(ModerationAPIRequest request) 22 | { 23 | return ( (StringUtils.isEmpty(request.getModel()) || request.getModel()==null) || (StringUtils.isEmpty(request.getInput()) || request.getInput()==null))?true:false; 24 | } 25 | 26 | 27 | /** 28 | * model and prompt are mandatory fields 29 | */ 30 | public static boolean checkParamForCompletion(CompletionRequest request) 31 | { 32 | return ( (StringUtils.isEmpty(request.getModel()) || request.getModel()==null) || (StringUtils.isEmpty(request.getPrompt()) || request.getPrompt()==null))?true:false; 33 | } 34 | 35 | /** 36 | * model , message (role and content) are mandatory fields 37 | */ 38 | public static boolean checkParamForChatCompletion_modelName(ChatCompletionRequest request) 39 | { 40 | return (StringUtils.isEmpty(request.getModel()) || request.getModel()==null)?true:false; 41 | } 42 | 43 | /** 44 | * model , message (role and content) are mandatory fields 45 | */ 46 | public static boolean checkParamForChatCompletion_Messages_role_content(ChatCompletionRequest request) 47 | { 48 | List messages = request.getMessages(); 49 | if(messages.size()<=0) 50 | { 51 | return true; 52 | } 53 | for(int i=0;i getModeration(@Header("Authorization")String accessToken, @Body ModerationAPIRequest request) throws IOException; 28 | 29 | 30 | //Newer models (2023–) gpt-4 (and gpt-4 turbo), gpt-3.5-turbo 31 | @POST("/v1/completions") 32 | Call getCompletion(@Header("Authorization")String accessToken, @Body CompletionRequest request)throws IOException; 33 | 34 | //Updated base models (2023) babbage-002, davinci-002 and Legacy models (2020–2022) text-davinci-003, text-davinci-002, davinci, curie, babbage, ada 35 | @POST("/v1/completions") 36 | Call completion_old(@Header("Authorization")String accessToken, @Body CompletionRequest request)throws IOException; 37 | 38 | 39 | @POST("/v1/chat/completions") 40 | Call chatCompletion(@Header("Authorization") String accessToken, @Body ChatCompletionRequest request) throws IOException; 41 | 42 | 43 | //gpt-4-vision-preview 44 | @POST("/v1/chat/completions") 45 | Call visionAPI(@Header("Authorization") String accessToken, @Body VisionApiRequest request) throws IOException; 46 | 47 | @POST("/v1/audio/speech") 48 | Call createSpeech(@Header("Authorization")String accessToken, @Body SpeechRequest request) throws IOException; 49 | 50 | @POST("/v1/audio/transcriptions") 51 | @Multipart 52 | Call createTranscriptions(@Header("Authorization")String accessToken, 53 | @Part MultipartBody.Part file, 54 | @Part("model") RequestBody model, 55 | @Part("language") RequestBody language, 56 | @Part("prompt") RequestBody prompt, 57 | @Part("response_format") RequestBody response_format, 58 | @Part("temperature")RequestBody temperature ) throws IOException; 59 | 60 | @POST("/v1/images/generations") 61 | Call createImage(@Header("Authorization")String accessToken, @Body ImageRequest imageRequest) throws IOException; 62 | 63 | @POST("/v1/images/edits") 64 | @Multipart 65 | Call createImageEdit(@Header("Authorization")String accessToken, @Part MultipartBody.Part image, @Part("prompt") RequestBody prompt )throws IOException; 66 | 67 | @POST("/v1/images/variations") 68 | @Multipart 69 | Call createImageVariation (@Header("Authorization")String accessToken, @Part MultipartBody.Part image, @Part("prompt") RequestBody prompt )throws IOException; 70 | 71 | @GET("/v1/models") 72 | Call getAllModels(@Header("Authorization")String accessToken)throws IOException; 73 | 74 | } 75 | -------------------------------------------------------------------------------- /src/main/java/io/github/namankhurpia/Documentation/RunnerForAsync.java: -------------------------------------------------------------------------------- 1 | package io.github.namankhurpia.Documentation; 2 | 3 | import io.github.namankhurpia.DAO.AsyncDAOImpl; 4 | import io.github.namankhurpia.Pojo.ChatCompletion.Message; 5 | import io.github.namankhurpia.Pojo.ChatCompletion.ChatCompletionRequest; 6 | import io.github.namankhurpia.Pojo.ChatCompletion.ChatCompletionResponse; 7 | import io.github.namankhurpia.Pojo.Moderations.ModerationAPIRequest; 8 | import io.github.namankhurpia.Pojo.Moderations.ModerationAPIResponse; 9 | import io.github.namankhurpia.Pojo.Vision.*; 10 | import io.github.namankhurpia.Service.EasyopenaiAsyncService; 11 | 12 | import java.io.File; 13 | import java.io.FileNotFoundException; 14 | import java.io.IOException; 15 | import java.util.ArrayList; 16 | import java.util.List; 17 | import java.util.Scanner; 18 | import java.util.concurrent.ExecutionException; 19 | 20 | public class RunnerForAsync { 21 | public static void main(String[] args) throws IOException, ExecutionException, InterruptedException { 22 | 23 | RunnerForAsync_chatCompletion(); 24 | RunnerForAsync_ModerationAPI(); 25 | RunnerForAsync_VisionAPI(); 26 | 27 | 28 | 29 | } 30 | 31 | public static void RunnerForAsync_chatCompletion() throws IOException, ExecutionException, InterruptedException { 32 | /** 33 | * Asynchronous chat 34 | */ 35 | ArrayList keys = readKeys(); 36 | EasyopenaiAsyncService easyopenaiAsyncService_chat = new EasyopenaiAsyncService(new AsyncDAOImpl()); 37 | 38 | Message message = new Message(); 39 | message.setRole("user"); 40 | message.setContent("what is the capital of combodia?"); 41 | 42 | List messages = new ArrayList<>(); 43 | messages.add(message); 44 | 45 | ChatCompletionRequest request_chat = new ChatCompletionRequest(); 46 | request_chat.setModel("gpt-3.5-turbo"); 47 | request_chat.setMessages(messages); //old conversations as well 48 | ChatCompletionResponse response_chat = easyopenaiAsyncService_chat.getAsyncChatCompletion(keys.get(0),request_chat); 49 | System.out.println(response_chat); 50 | } 51 | 52 | public static void RunnerForAsync_ModerationAPI() throws IOException, ExecutionException, InterruptedException { 53 | /** 54 | * Asynchronous moderation 55 | */ 56 | ArrayList keys = readKeys(); 57 | EasyopenaiAsyncService easyopenaiAsyncService_mod = new EasyopenaiAsyncService(new AsyncDAOImpl()); 58 | 59 | ModerationAPIRequest request_mod = new ModerationAPIRequest(); 60 | request_mod.setInput("kill me now"); 61 | request_mod.setModel("text-moderation-latest"); 62 | 63 | ModerationAPIResponse response_mod = easyopenaiAsyncService_mod.getASyncModeration(keys.get(0),request_mod); 64 | } 65 | 66 | public static void RunnerForAsync_VisionAPI() throws IOException, ExecutionException, InterruptedException { 67 | /** 68 | * Vision API Single Instance 69 | */ 70 | ArrayList keys = readKeys(); 71 | VisionApiRequest request = new VisionApiRequest(); 72 | 73 | ImageUrl url = new ImageUrl(); 74 | url.setUrl("https://images.pexels.com/photos/18907092/pexels-photo-18907092/free-photo-of-a-photo-of-the-golden-gate-bridge-in-the-sky.jpeg"); 75 | url.setDetail("low"); 76 | 77 | Content content1 = new Content(); 78 | content1.setText("What’s in this image?"); 79 | content1.setType("text"); 80 | 81 | Content content2 = new Content(); 82 | content2.setImageUrl(url); 83 | content2.setType("image_url"); 84 | 85 | ArrayList listofContent = new ArrayList<>(); 86 | listofContent.add(content1); 87 | listofContent.add(content2); 88 | 89 | MessageList messageList = new MessageList(); 90 | messageList.setRole("user"); 91 | messageList.setContent(listofContent); 92 | 93 | ArrayList listofMessage= new ArrayList<>(); 94 | listofMessage.add(messageList); 95 | 96 | request.setModel("gpt-4-vision-preview"); 97 | request.setMaxTokens(300); 98 | request.setMessages(listofMessage); 99 | 100 | EasyopenaiAsyncService easyopenaiAsyncService_mod = new EasyopenaiAsyncService(new AsyncDAOImpl()); 101 | VisionApiResponse res = easyopenaiAsyncService_mod.getAsyncVisionAPI(keys.get(0),request); 102 | System.out.println("Response is:"+res); 103 | 104 | 105 | 106 | } 107 | 108 | public static ArrayList readKeys() 109 | { 110 | String filePath = "keys.txt"; 111 | ArrayList keyList = new ArrayList<>(); 112 | 113 | // Open the file using Scanner 114 | try { 115 | File file = new File(filePath); 116 | Scanner scanner = new Scanner(file); 117 | 118 | // Read each line and extract keys 119 | while (scanner.hasNextLine()) { 120 | String line = scanner.nextLine(); 121 | // Assuming each line contains a key 122 | keyList.add(line); 123 | //System.out.println("Key: " + line); 124 | } 125 | 126 | // Close the scanner 127 | scanner.close(); 128 | } catch (FileNotFoundException e) { 129 | System.out.println("File not found: " + filePath); 130 | e.printStackTrace(); 131 | } 132 | return keyList; 133 | } 134 | 135 | 136 | } 137 | -------------------------------------------------------------------------------- /src/main/java/io/github/namankhurpia/Pojo/ChatCompletion/ChatCompletionRequest.java: -------------------------------------------------------------------------------- 1 | package io.github.namankhurpia.Pojo.ChatCompletion; 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty; 4 | import com.google.gson.annotations.SerializedName; 5 | import lombok.AllArgsConstructor; 6 | import lombok.Builder; 7 | import lombok.Data; 8 | import lombok.NoArgsConstructor; 9 | 10 | import java.util.List; 11 | import java.util.Map; 12 | 13 | @Builder 14 | @AllArgsConstructor 15 | @NoArgsConstructor 16 | @Data 17 | public class ChatCompletionRequest { 18 | 19 | 20 | /** 21 | * The messages to generate chat completions for, in the chat format.
23 | * see {@link Message} 24 | */ 25 | List messages; 26 | 27 | 28 | /** 29 | * ID of the model to use. 30 | */ 31 | String model; 32 | 33 | /** 34 | * Number between -2.0 and 2.0. Positive values penalize new tokens based on their existing frequency in the text so far, 35 | * decreasing the model's likelihood to repeat the same line verbatim. 36 | */ 37 | @JsonProperty("frequency_penalty") 38 | Double frequencyPenalty; 39 | 40 | /** 41 | * Accepts a json object that maps tokens (specified by their token ID in the tokenizer) to an associated bias value from -100 42 | * to 100. Mathematically, the bias is added to the logits generated by the model prior to sampling. The exact effect will 43 | * vary per model, but values between -1 and 1 should decrease or increase likelihood of selection; values like -100 or 100 44 | * should result in a ban or exclusive selection of the relevant token. 45 | */ 46 | @JsonProperty("logit_bias") 47 | Map logitBias; 48 | 49 | /** 50 | * Whether to return log probabilities of the output tokens or not. If true, returns the log probabilities of each output token returned in the content of message. This option is currently not available on the gpt-4-vision-preview model. 51 | */ 52 | @JsonProperty("logprobs") 53 | boolean logprobs; 54 | 55 | /** 56 | * An integer between 0 and 5 specifying the number of most likely tokens to return at each token position, each with an associated log probability. logprobs must be set to true if this parameter is used. 57 | */ 58 | @JsonProperty("top_logprobs") 59 | Integer topLogprobs; 60 | 61 | 62 | 63 | /** 64 | * The maximum number of tokens allowed for the generated answer. By default, the number of tokens the model can return will 65 | * be (4096 - prompt tokens). 66 | */ 67 | @JsonProperty("max_tokens") 68 | Integer maxTokens; 69 | 70 | /** 71 | * How many chat completion chatCompletionChoices to generate for each input message. 72 | */ 73 | Integer n; 74 | 75 | /** 76 | * Number between -2.0 and 2.0. Positive values penalize new tokens based on whether they appear in the text so far, 77 | * increasing the model's likelihood to talk about new topics. 78 | */ 79 | @JsonProperty("presence_penalty") 80 | Double presencePenalty; 81 | 82 | /** 83 | * 84 | */ 85 | @JsonProperty("response_format") 86 | Object responseFormat; 87 | 88 | 89 | 90 | /** 91 | * This feature is in Beta. If specified, our system will make a best effort to sample deterministically, such that repeated requests with the same seed and parameters should return the same result. Determinism is not guaranteed, and you should refer to the system_fingerprint response parameter to monitor changes in the backend. 92 | */ 93 | Double seed; 94 | 95 | /** 96 | * Up to 4 sequences where the API will stop generating further tokens. 97 | */ 98 | List stop; 99 | 100 | /** 101 | * If set, partial message deltas will be sent, like in ChatGPT. Tokens will be sent as data-only server-sent 103 | * events as they become available, with the stream terminated by a data: [DONE] message. 104 | */ 105 | Boolean stream; 106 | 107 | /** 108 | * What sampling temperature to use, between 0 and 2. Higher values like 0.8 will make the output more random, while lower 109 | * values like 0.2 will make it more focused and deterministic.
110 | * We generally recommend altering this or top_p but not both. 111 | */ 112 | Double temperature; 113 | 114 | /** 115 | * An alternative to sampling with temperature, called nucleus sampling, where the model considers the results of the tokens 116 | * with top_p probability mass. So 0.1 means only the tokens comprising the top 10% probability mass are considered.
117 | * We generally recommend altering this or temperature but not both. 118 | */ 119 | 120 | @SerializedName("top_p") 121 | @JsonProperty("top_p") 122 | Double topP; 123 | 124 | /** 125 | * A list of tools the model may call. Currently, only functions are supported as a tool. Use this to provide a list of functions the model may generate JSON inputs for. 126 | */ 127 | List tools; 128 | 129 | 130 | /** 131 | * Controls which (if any) function is called by the model. none means the model will not call a function and instead generates a message. auto means the model can pick between generating a message or calling a function. Specifying a particular function via {"type: "function", "function": {"name": "my_function"}} forces the model to call that function. 132 | * 133 | * none is the default when no functions are present. auto is the default if functions are present. 134 | * 135 | */ 136 | ToolChoice tool_choice; 137 | 138 | /** 139 | * A unique identifier representing your end-user, which will help OpenAI to monitor and detect abuse. 140 | */ 141 | String user; 142 | 143 | 144 | /** 145 | * Function_call is deprecated, use tool_choice 146 | */ 147 | 148 | 149 | /** 150 | * A list of the available functions. 151 | */ 152 | List functions; 153 | 154 | /** 155 | * Controls how the model responds to function calls, as specified in the OpenAI documentation. 156 | */ 157 | @JsonProperty("function_call") 158 | ChatCompletionRequestFunctionCall functionCall; 159 | 160 | @Builder 161 | @AllArgsConstructor 162 | @NoArgsConstructor 163 | public static class ChatCompletionRequestFunctionCall { 164 | String name; 165 | 166 | public static ChatCompletionRequestFunctionCall of(String name) { 167 | return new ChatCompletionRequestFunctionCall(name); 168 | } 169 | 170 | } 171 | 172 | } 173 | -------------------------------------------------------------------------------- /src/main/java/io/github/namankhurpia/Pojo/Completion/CompletionRequest.java: -------------------------------------------------------------------------------- 1 | package io.github.namankhurpia.Pojo.Completion; 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty; 4 | import lombok.Data; 5 | 6 | import java.util.Map; 7 | 8 | @Data 9 | public class CompletionRequest { 10 | /** 11 | * model 12 | * string 13 | * Required 14 | * ID of the model to use. You can use the List models API to see all of your available models, or see our Model overview for descriptions of them. 15 | */ 16 | @JsonProperty("model") 17 | String model; 18 | 19 | /** 20 | * prompt 21 | * string or array 22 | * Required 23 | * The prompt(s) to generate completions for, encoded as a string, array of strings, array of tokens, or array of token arrays. 24 | * 25 | * Note that <|endoftext|> is the document separator that the model sees during training, so if a prompt is not specified the model will generate as if from the beginning of a new document. 26 | */ 27 | @JsonProperty("prompt") 28 | String prompt; 29 | 30 | /** 31 | * 32 | * integer or null 33 | * Optional 34 | * Defaults to 1 35 | * Generates best_of completions server-side and returns the "best" (the one with the highest log probability per token). Results cannot be streamed. 36 | * When used with n, best_of controls the number of candidate completions and n specifies how many to return – best_of must be greater than n 37 | */ 38 | @JsonProperty("best_of") 39 | Integer best_of; 40 | 41 | /** 42 | * echo 43 | * boolean or null 44 | * Optional 45 | * Defaults to false 46 | * Echo back the prompt in addition to the completion 47 | */ 48 | @JsonProperty("echo") 49 | boolean echo; 50 | 51 | /** 52 | * Number or null 53 | * Optional 54 | * Defaults to 0 55 | * Number between -2.0 and 2.0. Positive values penalize new tokens based on their existing frequency in the text so far, decreasing the model's likelihood to repeat the same line verbatim. 56 | */ 57 | @JsonProperty("frequency_penalty") 58 | Double frequency_penalty; 59 | 60 | 61 | /** 62 | * map 63 | * Optional 64 | * Defaults to null 65 | * Modify the likelihood of specified tokens appearing in the completion. 66 | * 67 | * Accepts a JSON object that maps tokens (specified by their token ID in the GPT tokenizer) to an associated bias value from -100 to 100. You can use this tokenizer tool (which works for both GPT-2 and GPT-3) to convert text to token IDs. Mathematically, the bias is added to the logits generated by the model prior to sampling. The exact effect will vary per model, but values between -1 and 1 should decrease or increase likelihood of selection; values like -100 or 100 should result in a ban or exclusive selection of the relevant token. 68 | * 69 | * As an example, you can pass {"50256": -100} to prevent the <|endoftext|> token from being generated. 70 | */ 71 | @JsonProperty("logit_bias") 72 | Map logit_bias; 73 | 74 | 75 | /** 76 | * 77 | integer or null 78 | Optional 79 | Defaults to null 80 | Include the log probabilities on the logprobs most likely tokens, as well the chosen tokens. For example, if logprobs is 5, the API will return a list of the 5 most likely tokens. The API will always return the logprob of the sampled token, so there may be up to logprobs+1 elements in the response. 81 | The maximum value for logprobs is 5. 82 | */ 83 | @JsonProperty("logsprobs") 84 | Integer logsprobs; 85 | 86 | /** 87 | * integer or null 88 | * Optional 89 | * Defaults to 16 90 | * The maximum number of tokens to generate in the completion. 91 | * 92 | * The token count of your prompt plus max_tokens cannot exceed the model's context length. Example Python code for counting tokens. 93 | */ 94 | 95 | @JsonProperty("max_tokens") 96 | Integer max_tokens; 97 | 98 | /** 99 | * integer or null 100 | * Optional 101 | * Defaults to 1 102 | * How many completions to generate for each prompt. 103 | * 104 | * Note: Because this parameter generates many completions, it can quickly consume your token quota. Use carefully and ensure that you have reasonable settings for max_tokens and stop 105 | */ 106 | @JsonProperty("n") 107 | Integer n; 108 | 109 | /** 110 | * number or null 111 | * Optional 112 | * Defaults to 0 113 | * Number between -2.0 and 2.0. Positive values penalize new tokens based on whether they appear in the text so far, increasing the model's likelihood to talk about new topics. 114 | */ 115 | @JsonProperty("presence_penalty") 116 | Double presence_penalty; 117 | 118 | /** 119 | * integer or null 120 | * Optional 121 | * If specified, our system will make a best effort to sample deterministically, such that repeated requests with the same seed and parameters should return the same result. 122 | * 123 | * Determinism is not guaranteed, and you should refer to the system_fingerprint response parameter to monitor changes in the backend. 124 | */ 125 | @JsonProperty("seed") 126 | Integer seed; 127 | 128 | /** 129 | * string / array / null 130 | * Optional 131 | * Defaults to null 132 | * Up to 4 sequences where the API will stop generating further tokens. The returned text will not contain the stop sequence. 133 | */ 134 | @JsonProperty("stop") 135 | String stop; 136 | 137 | /** 138 | * boolean or null 139 | * Optional 140 | * Defaults to false 141 | * Whether to stream back partial progress. If set, tokens will be sent as data-only server-sent events as they become available, with the stream terminated by a data: [DONE] message. Example Python code. 142 | */ 143 | @JsonProperty("stream") 144 | boolean stream; 145 | 146 | /** 147 | * string or null 148 | * Optional 149 | * Defaults to null 150 | * The suffix that comes after a completion of inserted text. 151 | */ 152 | @JsonProperty("suffix") 153 | String suffix; 154 | 155 | /** 156 | * number or null 157 | * Optional 158 | * Defaults to 1 159 | * What sampling temperature to use, between 0 and 2. Higher values like 0.8 will make the output more random, while lower values like 0.2 will make it more focused and deterministic. 160 | * 161 | * We generally recommend altering this or top_p but not both. 162 | */ 163 | @JsonProperty("temperature") 164 | Double temperature; 165 | 166 | /** 167 | * number or null 168 | * Optional 169 | * Defaults to 1 170 | * An alternative to sampling with temperature, called nucleus sampling, where the model considers the results of the tokens with top_p probability mass. So 0.1 means only the tokens comprising the top 10% probability mass are considered. 171 | * 172 | * We generally recommend altering this or temperature but not both 173 | */ 174 | @JsonProperty("top_p") 175 | Double top_p; 176 | 177 | /** 178 | * user 179 | * string 180 | * Optional 181 | * A unique identifier representing your end-user, which can help OpenAI to monitor and detect abuse 182 | */ 183 | @JsonProperty("user") 184 | String user; 185 | 186 | 187 | public CompletionRequest() { 188 | 189 | } 190 | } 191 | -------------------------------------------------------------------------------- /pom.xml.versionsBackup: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | io.github.namankhurpia 8 | easyopenai 9 | 1.0-SNAPSHOT 10 | 11 | 12 | 13 | ossrh 14 | https://s01.oss.sonatype.org/content/repositories/snapshots 15 | 16 | 17 | ossrh 18 | https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/ 19 | 20 | 21 | 22 | 23 | 24 | 25 | org.sonatype.plugins 26 | nexus-staging-maven-plugin 27 | 1.6.7 28 | true 29 | 30 | ossrh 31 | https://s01.oss.sonatype.org/ 32 | true 33 | 34 | 35 | 36 | 37 | org.apache.maven.plugins 38 | maven-source-plugin 39 | 2.2.1 40 | 41 | 42 | attach-sources 43 | 44 | jar-no-fork 45 | 46 | 47 | 48 | 49 | 50 | 51 | org.apache.maven.plugins 52 | maven-javadoc-plugin 53 | 2.9.1 54 | 55 | 56 | attach-javadocs 57 | 58 | jar 59 | 60 | 61 | 62 | 63 | 64 | 65 | org.apache.maven.plugins 66 | maven-gpg-plugin 67 | 1.5 68 | 69 | 70 | sign-artifacts 71 | verify 72 | 73 | sign 74 | 75 | 76 | 0xD361D318 77 | 0xD361D318 78 | 79 | 80 | --pinentry-mode 81 | loopback 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | jar 93 | 94 | 95 | 18 96 | 18 97 | UTF-8 98 | 99 | EasyOpenAI 100 | https://github.com/namankhurpia/Easy-open-ai 101 | This is library for calling OpenAI APIs, includes functionality for concurrent calls and management. 102 | 103 | 104 | 105 | MIT License 106 | http://www.opensource.org/licenses/mit-license.php 107 | 108 | 109 | 110 | 111 | 112 | Naman Khurpia 113 | namankhurpia2@gmail.com 114 | io.github.namankhurpia 115 | http://namank.xyz 116 | 117 | 118 | 119 | 120 | scm:git:git://github.com/namankhurpia/Easy-open-ai.git 121 | scm:git:ssh://github.com:namankhurpia/Easy-open-ai.git 122 | https://github.com/namankhurpia/Easy-open-ai 123 | 124 | 125 | 126 | 127 | 128 | 129 | com.squareup.retrofit2 130 | retrofit 131 | 2.9.0 132 | 133 | 134 | 135 | com.squareup.retrofit2 136 | converter-gson 137 | 2.9.0 138 | 139 | 140 | 141 | 142 | com.squareup.okhttp3 143 | logging-interceptor 144 | 4.12.0 145 | 146 | 147 | 148 | 149 | com.squareup.okhttp3 150 | okhttp 151 | 4.12.0 152 | 153 | 154 | 155 | org.apache.commons 156 | commons-lang3 157 | 3.14.0 158 | 159 | 160 | 161 | org.projectlombok 162 | lombok 163 | 1.18.30 164 | provided 165 | 166 | 167 | 168 | 169 | com.fasterxml.jackson.core 170 | jackson-annotations 171 | 2.16.0 172 | 173 | 174 | 175 | 176 | com.fasterxml.jackson.core 177 | jackson-databind 178 | 2.16.0 179 | 180 | 181 | 182 | 183 | org.slf4j 184 | slf4j-api 185 | 2.0.9 186 | 187 | 188 | 189 | 190 | concurrent 191 | concurrent 192 | 1.3.4 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | -------------------------------------------------------------------------------- /src/main/java/io/github/namankhurpia/DAO/AsyncDAOImpl.java: -------------------------------------------------------------------------------- 1 | package io.github.namankhurpia.DAO; 2 | 3 | import io.github.namankhurpia.Exception.MalformedRequestException; 4 | import io.github.namankhurpia.Interfaces.AsyncApiInterface; 5 | import io.github.namankhurpia.Interfaces.RetrofitApiInterface; 6 | import io.github.namankhurpia.Pojo.ChatCompletion.ChatCompletionRequest; 7 | import io.github.namankhurpia.Pojo.ChatCompletion.ChatCompletionResponse; 8 | import io.github.namankhurpia.Pojo.Completion.CompletionResponse; 9 | import io.github.namankhurpia.Pojo.Moderations.ModerationAPIRequest; 10 | import io.github.namankhurpia.Pojo.Moderations.ModerationAPIResponse; 11 | import io.github.namankhurpia.Pojo.Vision.VisionApiRequest; 12 | import io.github.namankhurpia.Pojo.Vision.VisionApiResponse; 13 | import org.slf4j.Logger; 14 | import org.slf4j.LoggerFactory; 15 | import retrofit2.Call; 16 | import retrofit2.Callback; 17 | import retrofit2.Response; 18 | 19 | import java.io.IOException; 20 | import java.util.concurrent.CompletableFuture; 21 | import java.util.concurrent.ExecutionException; 22 | 23 | import static io.github.namankhurpia.Validators.ParameterCheckers.*; 24 | 25 | public class AsyncDAOImpl implements AsyncApiInterface { 26 | 27 | ModerationAPIResponse moderationAPIResponseObj; 28 | 29 | CompletionResponse completionResponseObj; 30 | 31 | ChatCompletionResponse chatCompletionResponseObj; 32 | 33 | VisionApiResponse visionApiResponseObj; 34 | 35 | private static Logger LOGGER = LoggerFactory.getLogger(AsyncDAOImpl.class); 36 | 37 | RetrofitApiInterface retrofitApiInterfaceObj; 38 | 39 | 40 | 41 | @Override 42 | public ModerationAPIResponse getASyncModeration(String accessToken, ModerationAPIRequest request) throws IOException, ExecutionException, InterruptedException { 43 | // Param checking 44 | if (checkParamForModeration(request)) { 45 | throw new MalformedRequestException("Request object has Model name empty or Input empty ", new Throwable()); 46 | } 47 | 48 | retrofitApiInterfaceObj = RetrofitAPIClient.getClient().create(RetrofitApiInterface.class); 49 | LOGGER.info("Making request " + accessToken + " with request " + request.toString()); 50 | 51 | 52 | CompletableFuture future = new CompletableFuture<>(); 53 | 54 | Call call = retrofitApiInterfaceObj.getModeration("Bearer "+accessToken, request); 55 | 56 | call.enqueue(new Callback() { 57 | @Override 58 | public void onResponse(Call call, Response response) { 59 | if (response.isSuccessful()) { 60 | moderationAPIResponseObj = response.body(); 61 | 62 | future.complete(response.body()); 63 | } 64 | else 65 | { 66 | int httpStatusCode = response.code(); 67 | String errorBody = response.errorBody() != null ? String.valueOf(response.errorBody()) : "Empty error body"; 68 | LOGGER.error("HTTP Status Code: " + httpStatusCode); 69 | LOGGER.error("Error Body: " + errorBody.toString()); 70 | future.completeExceptionally(new MalformedRequestException(errorBody, new Throwable(errorBody))); 71 | } 72 | } 73 | 74 | @Override 75 | public void onFailure(Call call, Throwable throwable) { 76 | future.completeExceptionally(throwable); 77 | } 78 | }); 79 | 80 | 81 | 82 | return future.get(); 83 | 84 | 85 | } 86 | 87 | @Override 88 | public ChatCompletionResponse getAsyncChatCompletion(String accessToken, ChatCompletionRequest request) throws IOException, ExecutionException, InterruptedException { 89 | //param checking 90 | if(checkParamForChatCompletion_Messages_role_content(request)) 91 | { 92 | throw new MalformedRequestException("messages Object has either role or content Empty", new Throwable()); 93 | } 94 | if(checkParamForChatCompletion_modelName(request)) 95 | { 96 | throw new MalformedRequestException("Request object has Model name empty, please specify a model you wish to use", new Throwable()); 97 | } 98 | 99 | retrofitApiInterfaceObj = RetrofitAPIClient.getClient().create(RetrofitApiInterface.class); 100 | 101 | LOGGER.info("making req" + accessToken + " with request "+ request.toString()); 102 | 103 | CompletableFuture future = new CompletableFuture<>(); 104 | 105 | Call call = retrofitApiInterfaceObj.chatCompletion("Bearer "+accessToken,request); 106 | 107 | call.enqueue(new Callback() { 108 | @Override 109 | public void onResponse(Call call, Response response) { 110 | if(response.isSuccessful()) 111 | { 112 | chatCompletionResponseObj = response.body(); 113 | future.complete(response.body()); 114 | LOGGER.info("Correct response" + chatCompletionResponseObj.toString()); 115 | 116 | } 117 | else 118 | { 119 | int httpStatusCode = response.code(); 120 | String errorBody = response.errorBody() != null ? String.valueOf(response.errorBody()) : "Empty error body"; 121 | LOGGER.error("Unsuccessful response with HTTP status code " + httpStatusCode + " and error body: " + errorBody); 122 | 123 | future.completeExceptionally(new MalformedRequestException(errorBody, new Throwable(errorBody))); 124 | 125 | } 126 | } 127 | 128 | @Override 129 | public void onFailure(Call call, Throwable throwable) { 130 | future.completeExceptionally(throwable); 131 | } 132 | 133 | 134 | 135 | }); 136 | 137 | 138 | 139 | 140 | return future.get(); 141 | } 142 | 143 | @Override 144 | public VisionApiResponse getAsyncVisionAPI(String accessToken, VisionApiRequest request) throws IOException, ExecutionException, InterruptedException { 145 | 146 | retrofitApiInterfaceObj = RetrofitAPIClient.getClient().create(RetrofitApiInterface.class); 147 | 148 | LOGGER.info("making req" + accessToken + " with request "+ request.toString()); 149 | 150 | CompletableFuture future = new CompletableFuture<>(); 151 | 152 | Call call = retrofitApiInterfaceObj.visionAPI("Bearer "+accessToken,request); 153 | 154 | call.enqueue(new Callback() { 155 | @Override 156 | public void onResponse(Call call, Response response) { 157 | if(response.isSuccessful()) 158 | { 159 | visionApiResponseObj = response.body(); 160 | future.complete(response.body()); 161 | LOGGER.info("Correct response" + visionApiResponseObj.toString()); 162 | 163 | } 164 | else 165 | { 166 | int httpStatusCode = response.code(); 167 | String errorBody = response.errorBody() != null ? String.valueOf(response.errorBody()) : "Empty error body"; 168 | LOGGER.error("Unsuccessful response with HTTP status code " + httpStatusCode + " and error body: " + errorBody); 169 | 170 | future.completeExceptionally(new MalformedRequestException(errorBody, new Throwable(errorBody))); 171 | 172 | } 173 | } 174 | 175 | @Override 176 | public void onFailure(Call call, Throwable throwable) { 177 | future.completeExceptionally(throwable); 178 | } 179 | 180 | 181 | 182 | }); 183 | 184 | 185 | 186 | 187 | return future.get(); 188 | } 189 | } 190 | -------------------------------------------------------------------------------- /src/main/java/io/github/namankhurpia/Documentation/RunnerForConcurrent.java: -------------------------------------------------------------------------------- 1 | package io.github.namankhurpia.Documentation; 2 | 3 | import io.github.namankhurpia.Pojo.ChatCompletion.Message; 4 | import io.github.namankhurpia.Pojo.ChatCompletion.ChatCompletionRequest; 5 | import io.github.namankhurpia.Pojo.Moderations.ModerationAPIRequest; 6 | import io.github.namankhurpia.Pojo.MyModels.ChatCompletionRequestList; 7 | import io.github.namankhurpia.Pojo.MyModels.ChatCompletionResponseList; 8 | import io.github.namankhurpia.Pojo.MyModels.ModerationRequestList; 9 | import io.github.namankhurpia.Pojo.MyModels.ModerationResponseList; 10 | import io.github.namankhurpia.Service.EasyopenaiConcurrentService; 11 | 12 | import java.io.File; 13 | import java.io.FileNotFoundException; 14 | import java.util.ArrayList; 15 | import java.util.List; 16 | import java.util.Scanner; 17 | 18 | import static io.github.namankhurpia.Interfaces.EndPoints.OPENAI_KEY; 19 | 20 | public class RunnerForConcurrent { 21 | public static void main(String[] args) { 22 | 23 | CallMultipleChatCompletionAPI_multikey_Test(); 24 | 25 | } 26 | 27 | public static void CallMultipleConcurrentAPI_Test() 28 | { 29 | /** 30 | * Moderation Concurrent call 31 | */ 32 | 33 | ModerationAPIRequest request = new ModerationAPIRequest(); 34 | request.setInput("kill me now"); 35 | request.setModel("text-moderation-latest"); 36 | 37 | ModerationAPIRequest request2 = new ModerationAPIRequest(); 38 | request2.setInput("hurray me now"); 39 | request2.setModel("text-moderation-latest"); 40 | 41 | ModerationAPIRequest request3 = new ModerationAPIRequest(); 42 | request3.setInput("yippee me now"); 43 | request3.setModel("text-moderation-latest"); 44 | 45 | ModerationAPIRequest request4 = new ModerationAPIRequest(); 46 | request4.setInput("KILL me now"); 47 | request4.setModel("text-moderation-latest"); 48 | 49 | ModerationRequestList requestList = new ModerationRequestList(new ArrayList()); 50 | requestList.add(request); 51 | requestList.add(request2); 52 | requestList.add(request3); 53 | requestList.add(request4); 54 | 55 | 56 | EasyopenaiConcurrentService concurrentCalls = new EasyopenaiConcurrentService(); 57 | ModerationResponseList responseList = concurrentCalls.CallMultipleModerationAPI(OPENAI_KEY,requestList); 58 | System.out.println(responseList); 59 | 60 | } 61 | 62 | public static void CallMultipleChatCompletionAPI_Test() 63 | { 64 | /** 65 | * Chat completion Multiple requests 66 | */ 67 | ChatCompletionRequestList list = new ChatCompletionRequestList(new ArrayList()); 68 | 69 | ChatCompletionRequest requestchat = new ChatCompletionRequest(); 70 | requestchat.setModel("gpt-3.5-turbo"); 71 | Message message = new Message(); 72 | message.setRole("user"); 73 | message.setContent("what is the capital of India?"); 74 | List messages = new ArrayList<>(); 75 | messages.add(message); 76 | requestchat.setMessages(messages); 77 | list.add(requestchat); 78 | 79 | 80 | ChatCompletionRequest requestchat2 = new ChatCompletionRequest(); 81 | requestchat2.setModel("gpt-3.5-turbo"); 82 | Message message2 = new Message(); 83 | message2.setRole("user"); 84 | message2.setContent("what is the capital of combodia?"); 85 | List messages2 = new ArrayList<>(); 86 | messages2.add(message2); 87 | requestchat2.setMessages(messages2); 88 | list.add(requestchat2); 89 | 90 | 91 | ChatCompletionRequest requestchat3 = new ChatCompletionRequest(); 92 | requestchat3.setModel("gpt-3.5-turbo"); 93 | Message message3 = new Message(); 94 | message3.setRole("user"); 95 | message3.setContent("what is the capital of new zealand?"); 96 | List messages3 = new ArrayList<>(); 97 | messages3.add(message3); 98 | requestchat3.setMessages(messages3); 99 | list.add(requestchat3); 100 | 101 | 102 | ChatCompletionRequest requestchat4 = new ChatCompletionRequest(); 103 | requestchat4.setModel("gpt-3.5-turbo"); 104 | Message message4 = new Message(); 105 | message4.setRole("user"); 106 | message4.setContent("what is the capital of hawaii? and what is 2+2?"); 107 | List messages4 = new ArrayList<>(); 108 | messages4.add(message4); 109 | requestchat4.setMessages(messages4); 110 | list.add(requestchat4); 111 | 112 | EasyopenaiConcurrentService concurrentCalls = new EasyopenaiConcurrentService(); 113 | 114 | ChatCompletionResponseList responseList = concurrentCalls.CallMultipleChatCompletionAPI(OPENAI_KEY, list); 115 | System.out.println(responseList); 116 | } 117 | 118 | public static void CallMultipleChatCompletionAPI_multikey_Test() 119 | { 120 | ArrayList keyList = readKeys(); 121 | EasyopenaiConcurrentService concurrentCalls = new EasyopenaiConcurrentService(); 122 | 123 | ChatCompletionRequestList list = new ChatCompletionRequestList(new ArrayList()); 124 | 125 | ChatCompletionRequest requestchat = new ChatCompletionRequest(); 126 | requestchat.setModel("gpt-3.5-turbo"); 127 | Message message = new Message(); 128 | message.setRole("user"); 129 | message.setContent("what is the capital of India?"); 130 | List messages = new ArrayList<>(); 131 | messages.add(message); 132 | requestchat.setMessages(messages); 133 | list.add(requestchat); 134 | 135 | 136 | ChatCompletionRequest requestchat2 = new ChatCompletionRequest(); 137 | requestchat2.setModel("gpt-3.5-turbo"); 138 | Message message2 = new Message(); 139 | message2.setRole("user"); 140 | message2.setContent("what is the capital of combodia?"); 141 | List messages2 = new ArrayList<>(); 142 | messages2.add(message2); 143 | requestchat2.setMessages(messages2); 144 | list.add(requestchat2); 145 | 146 | 147 | ChatCompletionRequest requestchat3 = new ChatCompletionRequest(); 148 | requestchat3.setModel("gpt-3.5-turbo"); 149 | Message message3 = new Message(); 150 | message3.setRole("user"); 151 | message3.setContent("what is the capital of new zealand?"); 152 | List messages3 = new ArrayList<>(); 153 | messages3.add(message3); 154 | requestchat3.setMessages(messages3); 155 | list.add(requestchat3); 156 | 157 | 158 | ChatCompletionRequest requestchat4 = new ChatCompletionRequest(); 159 | requestchat4.setModel("gpt-3.5-turbo"); 160 | Message message4 = new Message(); 161 | message4.setRole("user"); 162 | message4.setContent("what is the capital of hawaii? and what is 2+2?"); 163 | List messages4 = new ArrayList<>(); 164 | messages4.add(message4); 165 | requestchat4.setMessages(messages4); 166 | list.add(requestchat4); 167 | 168 | 169 | 170 | ChatCompletionResponseList responseList = concurrentCalls.CallMultipleChatCompletionAPI(keyList, list); 171 | System.out.println("response is"+responseList); 172 | } 173 | 174 | public static ArrayList readKeys() 175 | { 176 | String filePath = "keys.txt"; 177 | ArrayList keyList = new ArrayList<>(); 178 | 179 | // Open the file using Scanner 180 | try { 181 | File file = new File(filePath); 182 | Scanner scanner = new Scanner(file); 183 | 184 | // Read each line and extract keys 185 | while (scanner.hasNextLine()) { 186 | String line = scanner.nextLine(); 187 | // Assuming each line contains a key 188 | keyList.add(line); 189 | //System.out.println("Key: " + line); 190 | } 191 | 192 | // Close the scanner 193 | scanner.close(); 194 | } catch (FileNotFoundException e) { 195 | System.out.println("File not found: " + filePath); 196 | e.printStackTrace(); 197 | } 198 | return keyList; 199 | } 200 | } 201 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | io.github.namankhurpia 8 | easyopenai 9 | 1.0.8 10 | 11 | 12 | 13 | ossrh 14 | https://s01.oss.sonatype.org/content/repositories/snapshots 15 | 16 | 17 | ossrh 18 | https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/ 19 | 20 | 21 | 22 | 23 | 24 | 25 | org.sonatype.plugins 26 | nexus-staging-maven-plugin 27 | 1.6.7 28 | true 29 | 30 | ossrh 31 | https://s01.oss.sonatype.org/ 32 | true 33 | 34 | 35 | 36 | 37 | org.apache.maven.plugins 38 | maven-source-plugin 39 | 2.2.1 40 | 41 | 42 | attach-sources 43 | 44 | jar-no-fork 45 | 46 | 47 | 48 | 49 | 50 | 51 | org.apache.maven.plugins 52 | maven-javadoc-plugin 53 | 2.9.1 54 | 55 | 56 | attach-javadocs 57 | 58 | jar 59 | 60 | 61 | 62 | 63 | 64 | 65 | org.apache.maven.plugins 66 | maven-gpg-plugin 67 | 1.5 68 | 69 | 70 | sign-artifacts 71 | verify 72 | 73 | sign 74 | 75 | 76 | 9f7e68f3d361d318 77 | namankhurpia 78 | 79 | 80 | --pinentry-mode 81 | loopback 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | jar 93 | 94 | 95 | 18 96 | 18 97 | UTF-8 98 | 99 | EasyOpenAI 100 | https://github.com/namankhurpia/Easy-open-ai 101 | This is library for calling OpenAI APIs, includes functionality for concurrent calls and management. 102 | 103 | 104 | 105 | MIT License 106 | http://www.opensource.org/licenses/mit-license.php 107 | 108 | 109 | 110 | 111 | 112 | Naman Khurpia 113 | namankhurpia2@gmail.com 114 | io.github.namankhurpia 115 | http://namank.xyz 116 | 117 | 118 | 119 | 120 | scm:git:git://github.com/namankhurpia/Easy-open-ai.git 121 | scm:git:ssh://github.com:namankhurpia/Easy-open-ai.git 122 | https://github.com/namankhurpia/Easy-open-ai 123 | 124 | 125 | 126 | 127 | 128 | 129 | com.squareup.retrofit2 130 | retrofit 131 | 2.9.0 132 | 133 | 134 | 135 | com.squareup.retrofit2 136 | converter-gson 137 | 2.9.0 138 | 139 | 140 | 141 | 142 | com.squareup.okhttp3 143 | logging-interceptor 144 | 4.12.0 145 | 146 | 147 | 148 | 149 | com.squareup.okhttp3 150 | okhttp 151 | 4.12.0 152 | 153 | 154 | 155 | org.apache.commons 156 | commons-lang3 157 | 3.14.0 158 | 159 | 160 | 161 | org.projectlombok 162 | lombok 163 | 1.18.30 164 | provided 165 | 166 | 167 | 168 | 169 | com.fasterxml.jackson.core 170 | jackson-annotations 171 | 2.16.0 172 | 173 | 174 | 175 | 176 | com.fasterxml.jackson.core 177 | jackson-databind 178 | 2.16.0 179 | 180 | 181 | 182 | 183 | org.slf4j 184 | slf4j-api 185 | 2.0.9 186 | 187 | 188 | 189 | junit 190 | junit 191 | 4.13.2 192 | test 193 | 194 | 195 | 196 | org.mockito 197 | mockito-core 198 | 5.8.0 199 | test 200 | 201 | 202 | 203 | 204 | 205 | 206 | -------------------------------------------------------------------------------- /src/main/java/io/github/namankhurpia/Service/EasyopenaiConcurrentService.java: -------------------------------------------------------------------------------- 1 | package io.github.namankhurpia.Service; 2 | 3 | import io.github.namankhurpia.DAO.AsyncDAOImpl; 4 | import io.github.namankhurpia.Exception.InvalidSizeException; 5 | import io.github.namankhurpia.Interfaces.ConcurrentApiInterface; 6 | import io.github.namankhurpia.Pojo.ChatCompletion.ChatCompletionResponse; 7 | import io.github.namankhurpia.Pojo.Moderations.ModerationAPIResponse; 8 | import io.github.namankhurpia.Pojo.MyModels.ChatCompletionRequestList; 9 | import io.github.namankhurpia.Pojo.MyModels.ChatCompletionResponseList; 10 | import io.github.namankhurpia.Pojo.MyModels.ModerationRequestList; 11 | import io.github.namankhurpia.Pojo.MyModels.ModerationResponseList; 12 | import org.slf4j.Logger; 13 | import org.slf4j.LoggerFactory; 14 | 15 | import java.io.IOException; 16 | import java.util.ArrayList; 17 | import java.util.List; 18 | import java.util.concurrent.CompletableFuture; 19 | import java.util.concurrent.ExecutionException; 20 | 21 | import static io.github.namankhurpia.Interfaces.EndPoints.OPENAI_KEY; 22 | 23 | public class EasyopenaiConcurrentService implements ConcurrentApiInterface { 24 | 25 | private static Logger LOGGER = LoggerFactory.getLogger(EasyopenaiConcurrentService.class); 26 | 27 | 28 | @Override 29 | public ModerationResponseList CallMultipleModerationAPI(String key, ModerationRequestList requestList) { 30 | int n = requestList.size(); 31 | if(n<=0) 32 | { 33 | throw new InvalidSizeException("Moderation Request List must have atleast 1 instance",new Throwable()); 34 | } 35 | 36 | List> futures = new ArrayList<>(); 37 | EasyopenaiAsyncService AsyncObj = new EasyopenaiAsyncService(new AsyncDAOImpl()); 38 | 39 | for(int i=0;i resultFuture = CompletableFuture.supplyAsync(() ->{ 43 | try { 44 | return AsyncObj.getASyncModeration(OPENAI_KEY,requestList.get(index)); 45 | } catch (IOException e) { 46 | throw new RuntimeException(e); 47 | } catch (ExecutionException e) { 48 | throw new RuntimeException(e); 49 | } catch (InterruptedException e) { 50 | throw new RuntimeException(e); 51 | } 52 | 53 | 54 | 55 | }); 56 | 57 | futures.add(resultFuture); 58 | } 59 | 60 | CompletableFuture allOf = CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])); 61 | 62 | 63 | try { 64 | allOf.get(); // Wait for all CompletableFuture instances to complete 65 | } catch (InterruptedException | ExecutionException e) { 66 | e.printStackTrace(); 67 | } 68 | 69 | // Process the results 70 | List results = new ArrayList<>(); 71 | for (CompletableFuture future : futures) { 72 | try { 73 | results.add(future.get()); 74 | } catch (InterruptedException | ExecutionException e) { 75 | e.printStackTrace(); 76 | } 77 | } 78 | 79 | ModerationResponseList responseList = new ModerationResponseList(new ArrayList()); 80 | // Handle the combined result or individual results as needed 81 | responseList.addAll(results); 82 | return responseList; 83 | } 84 | 85 | @Override 86 | public ChatCompletionResponseList CallMultipleChatCompletionAPI(String key, ChatCompletionRequestList requestList) { 87 | int n = requestList.size(); 88 | if(n<=0) 89 | { 90 | throw new InvalidSizeException("Chat Completion Request List must have atleast 1 instance",new Throwable()); 91 | } 92 | 93 | List> futures = new ArrayList<>(); 94 | EasyopenaiAsyncService AsyncObj = new EasyopenaiAsyncService(new AsyncDAOImpl()); 95 | 96 | for(int i=0;i resultFuture = CompletableFuture.supplyAsync(() ->{ 101 | try { 102 | return AsyncObj.getAsyncChatCompletion(OPENAI_KEY,requestList.get(index)); 103 | } catch (IOException e) { 104 | throw new RuntimeException(e); 105 | } catch (ExecutionException e) { 106 | throw new RuntimeException(e); 107 | } catch (InterruptedException e) { 108 | throw new RuntimeException(e); 109 | } 110 | 111 | 112 | 113 | }); 114 | 115 | futures.add(resultFuture); 116 | } 117 | 118 | CompletableFuture allOf = CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])); 119 | 120 | 121 | try { 122 | allOf.get(); // Wait for all CompletableFuture instances to complete 123 | } catch (InterruptedException | ExecutionException e) { 124 | e.printStackTrace(); 125 | } 126 | 127 | // Process the results 128 | List results = new ArrayList<>(); 129 | for (CompletableFuture future : futures) { 130 | try { 131 | results.add(future.get()); 132 | } catch (InterruptedException | ExecutionException e) { 133 | e.printStackTrace(); 134 | } 135 | } 136 | 137 | ChatCompletionResponseList responseList = new ChatCompletionResponseList(new ArrayList()); 138 | // Handle the combined result or individual results as needed 139 | responseList.addAll(results); 140 | return responseList; 141 | } 142 | 143 | @Override 144 | public ChatCompletionResponseList CallMultipleChatCompletionAPI(ArrayList keyList, ChatCompletionRequestList requestList) { 145 | 146 | int n = requestList.size(); 147 | if(n<=0) 148 | { 149 | throw new InvalidSizeException("Chat Completion Request List must have atleast 1 instance",new Throwable()); 150 | } 151 | int keyListSize = keyList.size(); 152 | if(keyListSize<=0) 153 | { 154 | throw new InvalidSizeException("Atleast one key must be added to keylist",new Throwable()); 155 | } 156 | 157 | 158 | List> futures = new ArrayList<>(); 159 | EasyopenaiAsyncService AsyncObj = new EasyopenaiAsyncService(new AsyncDAOImpl()); 160 | 161 | 162 | for(int i=0;i resultFuture = CompletableFuture.supplyAsync(() ->{ 172 | try { 173 | return AsyncObj.getAsyncChatCompletion(key,requestList.get(index)); 174 | } catch (IOException e) { 175 | throw new RuntimeException(e); 176 | } catch (ExecutionException e) { 177 | throw new RuntimeException(e); 178 | } catch (InterruptedException e) { 179 | throw new RuntimeException(e); 180 | } 181 | 182 | 183 | 184 | }); 185 | 186 | futures.add(resultFuture); 187 | } 188 | 189 | CompletableFuture allOf = CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])); 190 | 191 | 192 | try { 193 | allOf.get(); // Wait for all CompletableFuture instances to complete 194 | } catch (InterruptedException | ExecutionException e) { 195 | e.printStackTrace(); 196 | } 197 | 198 | // Process the results 199 | List results = new ArrayList<>(); 200 | for (CompletableFuture future : futures) { 201 | try { 202 | results.add(future.get()); 203 | } catch (InterruptedException | ExecutionException e) { 204 | e.printStackTrace(); 205 | } 206 | } 207 | 208 | ChatCompletionResponseList responseList = new ChatCompletionResponseList(new ArrayList()); 209 | // Handle the combined result or individual results as needed 210 | responseList.addAll(results); 211 | return responseList; 212 | 213 | } 214 | 215 | } 216 | -------------------------------------------------------------------------------- /src/main/java/io/github/namankhurpia/Documentation/RunnerForSingleInstance.java: -------------------------------------------------------------------------------- 1 | package io.github.namankhurpia.Documentation; 2 | 3 | import io.github.namankhurpia.DAO.DAOImpl; 4 | import io.github.namankhurpia.Pojo.ChatCompletion.Message; 5 | import io.github.namankhurpia.Pojo.ChatCompletion.ChatCompletionRequest; 6 | import io.github.namankhurpia.Pojo.ChatCompletion.ChatCompletionResponse; 7 | import io.github.namankhurpia.Pojo.Image.ImageRequest; 8 | import io.github.namankhurpia.Pojo.Image.ImageResponse; 9 | import io.github.namankhurpia.Pojo.Models.ModelResponse; 10 | import io.github.namankhurpia.Pojo.Moderations.ModerationAPIRequest; 11 | import io.github.namankhurpia.Pojo.Moderations.ModerationAPIResponse; 12 | import io.github.namankhurpia.Pojo.MyModels.EasyVisionRequest; 13 | import io.github.namankhurpia.Pojo.Speech.EasyTranscriptionRequest; 14 | import io.github.namankhurpia.Pojo.Speech.SpeechRequest; 15 | import io.github.namankhurpia.Pojo.Vision.*; 16 | import io.github.namankhurpia.Service.EasyTranscriptionService; 17 | import io.github.namankhurpia.Service.EasyVisionService; 18 | import io.github.namankhurpia.Service.EasyopenaiService; 19 | import okhttp3.MediaType; 20 | import okhttp3.MultipartBody; 21 | import okhttp3.RequestBody; 22 | import okhttp3.ResponseBody; 23 | 24 | import java.io.File; 25 | import java.io.FileNotFoundException; 26 | import java.io.IOException; 27 | import java.util.ArrayList; 28 | import java.util.List; 29 | import java.util.Scanner; 30 | import java.util.concurrent.ExecutionException; 31 | 32 | public class RunnerForSingleInstance { 33 | 34 | public static void main(String[] args) throws IOException, ExecutionException, InterruptedException { 35 | //runMoDerationSingleInstance(); 36 | //runVisionAPI(); 37 | //runEasyVisionAPI(); 38 | //runEasyVisionAPI2(); 39 | //runEasyMoDerationSingleInstance(); 40 | //runEasyChatCompletionSingleInstance(); 41 | //TestForSpeech(); 42 | //TestForTranscription(); 43 | //TestForEasyTranscription(); 44 | //TestForImageGeneration(); 45 | GetAllModels(); 46 | 47 | } 48 | 49 | 50 | 51 | public static void runEasyVisionAPI()throws IOException 52 | { 53 | 54 | /** 55 | * EASY VISION API 56 | */ 57 | ArrayList keys = readKeys(); 58 | EasyVisionRequest request = new EasyVisionRequest(); 59 | request.setModel("gpt-4-vision-preview"); 60 | request.setPrompt("What are the difference between these images"); 61 | 62 | ArrayList imageurls = new ArrayList<>(); 63 | imageurls.add("https://images.pexels.com/photos/268533/pexels-photo-268533.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1"); 64 | imageurls.add("https://images.pexels.com/photos/36717/amazing-animal-beautiful-beautifull.jpg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1"); 65 | request.setImageUrls(imageurls); 66 | 67 | EasyVisionService obj = new EasyVisionService(); 68 | VisionApiResponse response = obj.VisionAPI(keys.get(0),request); 69 | System.out.println(response); 70 | 71 | 72 | } 73 | 74 | public static void runEasyVisionAPI2()throws IOException 75 | { 76 | /** 77 | * EASY VISION API - ONE LINER 78 | */ 79 | VisionApiResponse response = new EasyVisionService().VisionAPI(readKeys().get(0), new EasyVisionRequest() 80 | .setModel("gpt-4-vision-preview") 81 | .setPrompt("What are the difference between these images") 82 | .setMaxtokens(300) 83 | .setImageUrls(new ArrayList() {{ 84 | add("https://images.pexels.com/photos/268533/pexels-photo-268533.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1"); 85 | add("https://images.pexels.com/photos/36717/amazing-animal-beautiful-beautifull.jpg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1"); 86 | }})); 87 | 88 | System.out.println(response); 89 | } 90 | 91 | public static void runVisionAPI() throws IOException 92 | { 93 | /** 94 | * Vision API Single Instance 95 | */ 96 | ArrayList keys = readKeys(); 97 | VisionApiRequest request = new VisionApiRequest(); 98 | 99 | ImageUrl url = new ImageUrl(); 100 | url.setUrl("https://images.pexels.com/photos/18907092/pexels-photo-18907092/free-photo-of-a-photo-of-the-golden-gate-bridge-in-the-sky.jpeg"); 101 | url.setDetail("low"); 102 | 103 | Content content1 = new Content(); 104 | content1.setText("What’s in this image?"); 105 | content1.setType("text"); 106 | 107 | Content content2 = new Content(); 108 | content2.setImageUrl(url); 109 | content2.setType("image_url"); 110 | 111 | ArrayList listofContent = new ArrayList<>(); 112 | listofContent.add(content1); 113 | listofContent.add(content2); 114 | 115 | MessageList messageList = new MessageList(); 116 | messageList.setRole("user"); 117 | messageList.setContent(listofContent); 118 | 119 | ArrayList listofMessage= new ArrayList<>(); 120 | listofMessage.add(messageList); 121 | 122 | request.setModel("gpt-4-vision-preview"); 123 | request.setMaxTokens(300); 124 | request.setMessages(listofMessage); 125 | 126 | System.out.println(request); 127 | 128 | EasyopenaiService obj = new EasyopenaiService(new DAOImpl()); 129 | VisionApiResponse res = obj.visionAPI(keys.get(0),request); 130 | System.out.println("Response is:"+res); 131 | 132 | 133 | 134 | 135 | } 136 | 137 | public static void runMoDerationSingleInstance() throws IOException { 138 | /** 139 | * Moderation API single 140 | */ 141 | ArrayList keys = readKeys(); 142 | ModerationAPIRequest request = new ModerationAPIRequest(); 143 | request.setInput("hello from the other side kill me now"); 144 | request.setModel("text-moderation-latest"); 145 | 146 | EasyopenaiService obj = new EasyopenaiService(new DAOImpl()); 147 | ModerationAPIResponse res = obj.getmoderation(keys.get(0),request); 148 | System.out.println("response is"+ res); 149 | 150 | 151 | 152 | 153 | } 154 | 155 | 156 | public static void runEasyMoDerationSingleInstance() throws IOException { 157 | /** 158 | * Moderation API single 159 | */ 160 | ArrayList keys = readKeys(); 161 | 162 | ModerationAPIRequest request = ModerationAPIRequest.builder() 163 | .model("text-moderation-latest") 164 | .input("hello from the other side kill me now") 165 | .build(); 166 | 167 | ModerationAPIResponse res = new EasyopenaiService(new DAOImpl()).getmoderation(keys.get(0),request); 168 | System.out.println("response is"+ res); 169 | 170 | 171 | } 172 | 173 | 174 | public static void runChatCompletionSingleInstance() throws IOException{ 175 | /** 176 | * Chat Completion API single 177 | */ 178 | ArrayList keys = readKeys(); 179 | EasyopenaiService obj = new EasyopenaiService(new DAOImpl()); 180 | 181 | Message message = new Message(); 182 | message.setRole("user"); 183 | message.setContent("what is the capital of combodia?"); 184 | 185 | List messages = new ArrayList<>(); 186 | messages.add(message); 187 | 188 | ChatCompletionRequest request = new ChatCompletionRequest(); 189 | request.setModel("gpt-3.5-turbo"); 190 | request.setMessages(messages); //old conversations as well 191 | ChatCompletionResponse res = obj.chatCompletion(keys.get(0),request); 192 | 193 | } 194 | 195 | public static void runEasyChatCompletionSingleInstance() throws IOException{ 196 | /** 197 | * Chat Completion API single 198 | */ 199 | ArrayList keys = readKeys(); 200 | 201 | Message message = Message.builder() 202 | .role("user") 203 | .content("what is the capital of Cambodia?") 204 | .build(); 205 | 206 | List messages = new ArrayList<>(); 207 | messages.add(message); 208 | 209 | ChatCompletionRequest request = ChatCompletionRequest.builder() 210 | .model("gpt-3.5-turbo") 211 | .messages(messages) 212 | .build(); 213 | 214 | ChatCompletionResponse response = new EasyopenaiService(new DAOImpl()).chatCompletion(keys.get(0),request); 215 | System.out.println(response); 216 | 217 | } 218 | 219 | 220 | public static void TestForSpeech() throws IOException { 221 | /** 222 | * Speech generation API single 223 | */ 224 | ArrayList keys = readKeys(); 225 | SpeechRequest request = SpeechRequest.builder() 226 | .model("tts-1") 227 | .input("The quick brown fox jumped over the lazy dog.") 228 | .voice("alloy") 229 | .build(); 230 | 231 | ResponseBody response = new EasyopenaiService(new DAOImpl()).createSpeech(keys.get(0),request); 232 | 233 | 234 | } 235 | 236 | 237 | public static void TestForTranscription() throws IOException { 238 | /** 239 | * Speech generation API single 240 | */ 241 | File audioFile = new File("/Users/namankhurpia/Desktop/audio.mp3"); 242 | MultipartBody.Part filePart = MultipartBody.Part.createFormData( 243 | "file", 244 | audioFile.getName(), 245 | RequestBody.create(MediaType.parse("audio/*"), audioFile) 246 | ); 247 | 248 | ArrayList keys = readKeys(); 249 | RequestBody model = RequestBody.create(MediaType.parse("text/plain"), "whisper-1"); 250 | RequestBody language = RequestBody.create(MediaType.parse("text/plain"), ""); 251 | RequestBody prompt = RequestBody.create(MediaType.parse("text/plain"), ""); 252 | RequestBody response_format = RequestBody.create(MediaType.parse("text/plain"), ""); 253 | RequestBody temperature = RequestBody.create(MediaType.parse("text/plain"), ""); 254 | 255 | ResponseBody response = new EasyopenaiService(new DAOImpl()).createTranscriptions(keys.get(0), filePart,model, language,prompt,response_format,temperature); 256 | System.out.println(response.string()); 257 | 258 | 259 | } 260 | 261 | public static void TestForEasyTranscription() throws IOException { 262 | ArrayList keys = readKeys(); 263 | 264 | EasyTranscriptionRequest request = EasyTranscriptionRequest.builder() 265 | .filepath("/Users/namankhurpia/Desktop/audio.mp3") 266 | .model("whisper-1") 267 | .build(); 268 | 269 | ResponseBody response = new EasyTranscriptionService().EasyTranscription(keys.get(0), request); 270 | System.out.println(response.string()); 271 | } 272 | 273 | public static void TestForImageGeneration()throws IOException{ 274 | ArrayList keys = readKeys(); 275 | 276 | ImageRequest imageRequest = ImageRequest.builder() 277 | .prompt("Generate a cute dog playing with frizbee") 278 | .model("dall-e-2") 279 | .build(); 280 | 281 | ImageResponse response = new EasyopenaiService(new DAOImpl()).createImage(keys.get(0),imageRequest); 282 | System.out.println(response); 283 | 284 | } 285 | 286 | private static void GetAllModels() throws IOException { 287 | ArrayList keys = readKeys(); 288 | ModelResponse response = new EasyopenaiService(new DAOImpl()).getAllModels(keys.get(0)); 289 | System.out.println(response); 290 | 291 | } 292 | 293 | 294 | 295 | 296 | public static ArrayList readKeys() 297 | { 298 | String filePath = "keys.txt"; 299 | ArrayList keyList = new ArrayList<>(); 300 | 301 | // Open the file using Scanner 302 | try { 303 | File file = new File(filePath); 304 | Scanner scanner = new Scanner(file); 305 | 306 | // Read each line and extract keys 307 | while (scanner.hasNextLine()) { 308 | String line = scanner.nextLine(); 309 | // Assuming each line contains a key 310 | keyList.add(line); 311 | //System.out.println("Key: " + line); 312 | } 313 | 314 | // Close the scanner 315 | scanner.close(); 316 | } catch (FileNotFoundException e) { 317 | System.out.println("File not found: " + filePath); 318 | e.printStackTrace(); 319 | } 320 | return keyList; 321 | } 322 | 323 | 324 | } -------------------------------------------------------------------------------- /src/main/java/io/github/namankhurpia/DAO/DAOImpl.java: -------------------------------------------------------------------------------- 1 | package io.github.namankhurpia.DAO; 2 | 3 | import io.github.namankhurpia.Exception.MalformedRequestException; 4 | import io.github.namankhurpia.Interfaces.DaoInterface; 5 | import io.github.namankhurpia.Interfaces.RetrofitApiInterface; 6 | import io.github.namankhurpia.Pojo.ChatCompletion.ChatCompletionRequest; 7 | import io.github.namankhurpia.Pojo.ChatCompletion.ChatCompletionResponse; 8 | import io.github.namankhurpia.Pojo.Completion.CompletionRequest; 9 | import io.github.namankhurpia.Pojo.Completion.CompletionResponse; 10 | import io.github.namankhurpia.Pojo.Image.ImageRequest; 11 | import io.github.namankhurpia.Pojo.Image.ImageResponse; 12 | import io.github.namankhurpia.Pojo.Models.ModelResponse; 13 | import io.github.namankhurpia.Pojo.Moderations.ModerationAPIRequest; 14 | import io.github.namankhurpia.Pojo.Moderations.ModerationAPIResponse; 15 | 16 | import io.github.namankhurpia.Pojo.Speech.SpeechRequest; 17 | import io.github.namankhurpia.Pojo.Vision.VisionApiRequest; 18 | import io.github.namankhurpia.Pojo.Vision.VisionApiResponse; 19 | import okhttp3.MultipartBody; 20 | import okhttp3.RequestBody; 21 | import okhttp3.ResponseBody; 22 | import org.slf4j.Logger; 23 | import org.slf4j.LoggerFactory; 24 | import retrofit2.*; 25 | 26 | import java.io.IOException; 27 | 28 | import static io.github.namankhurpia.Validators.ParameterCheckers.*; 29 | 30 | 31 | public class DAOImpl implements DaoInterface { 32 | 33 | 34 | 35 | 36 | ModerationAPIResponse moderationAPIResponseObj; 37 | CompletionResponse completionResponseObj; 38 | 39 | ChatCompletionResponse chatCompletionResponseObj; 40 | 41 | VisionApiResponse visionApiResponseObj; 42 | 43 | ResponseBody responseBodyObj; 44 | 45 | ImageResponse imageResponse; 46 | 47 | ModelResponse modelResponse; 48 | 49 | private static Logger LOGGER = LoggerFactory.getLogger(DAOImpl.class); 50 | 51 | RetrofitApiInterface retrofitApiInterfaceObj; 52 | 53 | 54 | 55 | @Override 56 | public ModerationAPIResponse getmoderation(String accessToken, ModerationAPIRequest request) throws IOException { 57 | 58 | 59 | // Param checking 60 | if (checkParamForModeration(request)) { 61 | throw new MalformedRequestException("Request object has Model name empty or Input empty ", new Throwable()); 62 | } 63 | 64 | retrofitApiInterfaceObj = RetrofitAPIClient.getClient().create(RetrofitApiInterface.class); 65 | LOGGER.info("Making request " + accessToken + " with request " + request.toString()); 66 | 67 | 68 | Call call = retrofitApiInterfaceObj.getModeration("Bearer "+accessToken, request); 69 | 70 | try { 71 | Response response = call.execute(); 72 | 73 | if (response.isSuccessful()) { 74 | moderationAPIResponseObj = response.body(); 75 | System.out.println(moderationAPIResponseObj.toString()); 76 | } else { 77 | int httpStatusCode = response.code(); 78 | String errorBody = response.errorBody() != null ? String.valueOf(response.errorBody()) : "Empty error body"; 79 | String errorBodyString = response.errorBody().string(); 80 | System.out.println("Unsuccessful response with HTTP status code " + httpStatusCode + " and error body: " + errorBodyString); 81 | 82 | throw new MalformedRequestException(errorBody, new Throwable(errorBody)); 83 | 84 | } 85 | } catch (IOException e) { 86 | // Handle IO exception 87 | System.out.println("IOException: " + e.getMessage()); 88 | throw e; 89 | } 90 | 91 | return moderationAPIResponseObj; 92 | } 93 | 94 | @Override 95 | public CompletionResponse getCompletion(String accessToken, CompletionRequest request) throws IOException { 96 | //param checking 97 | if(checkParamForCompletion(request)) 98 | { 99 | throw new MalformedRequestException("Request object has Model name empty or promp empty ", new Throwable()); 100 | } 101 | 102 | retrofitApiInterfaceObj = RetrofitAPIClient.getClient().create(RetrofitApiInterface.class); 103 | 104 | LOGGER.info("making req" + accessToken + " with request "+ request.toString()); 105 | Call call = retrofitApiInterfaceObj.getCompletion("Bearer "+accessToken,request); 106 | Response response = call.execute(); 107 | 108 | if(response.isSuccessful()) 109 | { 110 | completionResponseObj = response.body(); 111 | LOGGER.info("Correct response" + completionResponseObj.toString()); 112 | } 113 | else 114 | { 115 | int httpStatusCode = response.code(); 116 | String errorBody = response.errorBody() != null ? response.errorBody().string() : "Empty error body"; 117 | String errorBodyString = response.errorBody().string(); 118 | System.out.println("Unsuccessful response with HTTP status code " + httpStatusCode + " and error body: " + errorBodyString); 119 | throw new MalformedRequestException(errorBody, new Throwable(errorBody)); 120 | } 121 | 122 | return completionResponseObj; 123 | } 124 | 125 | 126 | 127 | @Override 128 | public ChatCompletionResponse chatCompletion(String accessToken, ChatCompletionRequest request) throws IOException { 129 | //param checking 130 | if(checkParamForChatCompletion_Messages_role_content(request)) 131 | { 132 | throw new MalformedRequestException("messages Object has either role or content Empty", new Throwable()); 133 | } 134 | if(checkParamForChatCompletion_modelName(request)) 135 | { 136 | throw new MalformedRequestException("Request object has Model name empty, please specify a model you wish to use", new Throwable()); 137 | } 138 | 139 | retrofitApiInterfaceObj = RetrofitAPIClient.getClient().create(RetrofitApiInterface.class); 140 | 141 | LOGGER.info("making req" + accessToken + " with request "+ request.toString()); 142 | Call call = retrofitApiInterfaceObj.chatCompletion("Bearer "+accessToken,request); 143 | Response response = call.execute(); 144 | 145 | if(response.isSuccessful()) 146 | { 147 | chatCompletionResponseObj = response.body(); 148 | LOGGER.info("Correct response" + chatCompletionResponseObj.toString()); 149 | } 150 | else 151 | { 152 | int httpStatusCode = response.code(); 153 | String errorBody = response.errorBody() != null ? String.valueOf(response.errorBody()) : "Empty error body"; 154 | String errorBodyString = response.errorBody().string(); 155 | System.out.println("Unsuccessful response with HTTP status code " + httpStatusCode + " and error body: " + errorBodyString); 156 | throw new MalformedRequestException(errorBody, new Throwable(errorBody)); 157 | 158 | } 159 | 160 | 161 | 162 | 163 | return chatCompletionResponseObj; 164 | } 165 | 166 | @Override 167 | public VisionApiResponse visionAPI(String accessToken, VisionApiRequest request) throws IOException { 168 | 169 | retrofitApiInterfaceObj = RetrofitAPIClient.getClient().create(RetrofitApiInterface.class); 170 | LOGGER.info("making req" + accessToken + " with request "+ request.toString()); 171 | 172 | Call call = retrofitApiInterfaceObj.visionAPI("Bearer "+accessToken,request); 173 | Response response = call.execute(); 174 | 175 | if(response.isSuccessful()) 176 | { 177 | visionApiResponseObj = response.body(); 178 | LOGGER.info("Correct response" + visionApiResponseObj.toString()); 179 | } 180 | else { 181 | int httpStatusCode = response.code(); 182 | 183 | String errorBody = response.errorBody() != null ? String.valueOf(response.errorBody()) : "Empty error body"; 184 | String errorBodyString = response.errorBody().string(); 185 | System.out.println("Unsuccessful response with HTTP status code " + httpStatusCode + " and error body: " + errorBodyString); 186 | throw new MalformedRequestException(errorBody, new Throwable(errorBody)); 187 | 188 | } 189 | 190 | return visionApiResponseObj; 191 | } 192 | 193 | @Override 194 | public ResponseBody createSpeech(String accessToken, SpeechRequest request) throws IOException{ 195 | 196 | retrofitApiInterfaceObj = RetrofitAPIClient.getClient().create(RetrofitApiInterface.class); 197 | LOGGER.info("making req" + accessToken + " with request "+ request.toString()); 198 | 199 | Call call = retrofitApiInterfaceObj.createSpeech("Bearer "+accessToken, request); 200 | Response response = call.execute(); 201 | 202 | if(response.isSuccessful()) 203 | { 204 | responseBodyObj= response.body(); 205 | LOGGER.info("Correct response" + responseBodyObj.toString()); 206 | } 207 | else { 208 | int httpStatusCode = response.code(); 209 | 210 | String errorBody = response.errorBody() != null ? String.valueOf(response.errorBody()) : "Empty error body"; 211 | String errorBodyString = response.errorBody().string(); 212 | System.out.println("Unsuccessful response with HTTP status code " + httpStatusCode + " and error body: " + errorBodyString); 213 | throw new MalformedRequestException(errorBody, new Throwable(errorBody)); 214 | 215 | } 216 | 217 | return responseBodyObj; 218 | 219 | } 220 | 221 | @Override 222 | public ResponseBody createTranscriptions(String accessToken, MultipartBody.Part file, RequestBody model, RequestBody language, RequestBody prompt, RequestBody response_format, RequestBody temperature) throws IOException { 223 | retrofitApiInterfaceObj = RetrofitAPIClient.getClient().create(RetrofitApiInterface.class); 224 | LOGGER.info("making req" + accessToken + " with request "); 225 | 226 | Call call = retrofitApiInterfaceObj.createTranscriptions("Bearer "+accessToken,file ,model, language, prompt, response_format, temperature); 227 | Response response = call.execute(); 228 | 229 | if(response.isSuccessful()) 230 | { 231 | responseBodyObj= response.body(); 232 | LOGGER.info("Correct response" + responseBodyObj.toString()); 233 | } 234 | else { 235 | int httpStatusCode = response.code(); 236 | 237 | String errorBody = response.errorBody() != null ? String.valueOf(response.errorBody()) : "Empty error body"; 238 | String errorBodyString = response.errorBody().string(); 239 | System.out.println("Unsuccessful response with HTTP status code " + httpStatusCode + " and error body: " + errorBodyString); 240 | 241 | throw new MalformedRequestException(errorBody, new Throwable(errorBody)); 242 | 243 | 244 | } 245 | 246 | return responseBodyObj; 247 | } 248 | 249 | @Override 250 | public ImageResponse createImage(String accessToken, ImageRequest imageRequest) throws IOException { 251 | retrofitApiInterfaceObj = RetrofitAPIClient.getClient().create(RetrofitApiInterface.class); 252 | LOGGER.info("making req" + accessToken + " with request "+ imageRequest); 253 | 254 | Call call = retrofitApiInterfaceObj.createImage("Bearer "+ accessToken, imageRequest); 255 | Response response = call.execute(); 256 | 257 | if(response.isSuccessful()) 258 | { 259 | imageResponse= response.body(); 260 | LOGGER.info("Correct response" + imageResponse.toString()); 261 | } 262 | else { 263 | int httpStatusCode = response.code(); 264 | 265 | String errorBody = response.errorBody() != null ? String.valueOf(response.errorBody()) : "Empty error body"; 266 | String errorBodyString = response.errorBody().string(); 267 | System.out.println("Unsuccessful response with HTTP status code " + httpStatusCode + " and error body: " + errorBodyString); 268 | 269 | throw new MalformedRequestException(errorBody, new Throwable(errorBody)); 270 | 271 | 272 | } 273 | 274 | return imageResponse; 275 | } 276 | 277 | @Override 278 | public ModelResponse getAllModels(String accessToken) throws IOException { 279 | retrofitApiInterfaceObj = RetrofitAPIClient.getClient().create(RetrofitApiInterface.class); 280 | LOGGER.info("making req" + accessToken ); 281 | 282 | Call call = retrofitApiInterfaceObj.getAllModels("Bearer "+ accessToken); 283 | Response response = call.execute(); 284 | 285 | if(response.isSuccessful()) 286 | { 287 | modelResponse= response.body(); 288 | LOGGER.info("Correct response" + modelResponse.toString()); 289 | } 290 | else { 291 | int httpStatusCode = response.code(); 292 | 293 | String errorBody = response.errorBody() != null ? String.valueOf(response.errorBody()) : "Empty error body"; 294 | String errorBodyString = response.errorBody().string(); 295 | System.out.println("Unsuccessful response with HTTP status code " + httpStatusCode + " and error body: " + errorBodyString); 296 | 297 | throw new MalformedRequestException(errorBody, new Throwable(errorBody)); 298 | 299 | 300 | } 301 | 302 | return modelResponse; 303 | } 304 | 305 | 306 | } 307 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Easy-open-ai 2 | This repository contains the community-maintained library for OpenAI's API in java, the easiest way to use GPT 3/4 in your applications. 3 | 4 | [![Maven Central](https://maven-badges.herokuapp.com/maven-central/io.github.namankhurpia/easyopenai/badge.svg)](https://maven-badges.herokuapp.com/maven-central/io.github.namankhurpia/easyopenai) 5 | 6 | [![Your Custom Badge](https://img.shields.io/badge/Easyopenai-1.0.8-brightgreen)](https://central.sonatype.com/artifact/io.github.namankhurpia/easyopenai) 7 | 8 | ## Overview 9 | 10 | This Java library (community-maintained Library) provides a convenient way to interact with OpenAI's API for both Moderation and Chat Completion. The library encapsulates the necessary details, making it easy to integrate OpenAI's powerful models into your Java applications. This project is not maintained by OPENAI, this is an unofficial library. 11 | 12 | ## Table of Contents 13 | 14 | - [Dependencies](#Dependencies) 15 | 16 | ### Single Instance 17 | 18 | - [Chat Completion API](#chat-completion-api) 19 | - [Moderation API](#moderation-api) 20 | - [Easy Vision API](#easy-vision-api) or [Vision API](#vision-api) (original provided by OpenAI) 21 | - [Speech API](#speech-api) 22 | - [Easy Transcription API](#easy-transcription-api) or [Transcription API](#transcription-api) (original provided by OpenAI) 23 | - [Image generation API](#image-generation-api) also called as DALL-E API 24 | 25 | ### Asynchronous 26 | 27 | - [Async Chat Completion API](#async-chat-completion-api) 28 | - [Async Moderation API](#async-moderation-api) 29 | 30 | ### Multi-Asynchronous 31 | 32 | - [Multithreaded Async Chat Completion API](#multithreaded-async-chat-completion-api) 33 | - [Multithreaded Async Moderation API](#multithreaded-async-moderation-api) 34 | 35 | 36 | ### Multi-Asynchronous-MultiKey 37 | 38 | - [EMMC EasyOpenAI Multithreaded MultiKey ChatCompletionAPI](#EMMC-EasyOpenAI-Multithreaded-MultiKey-ChatCompletionAPI) 39 | 40 | 41 | # Contributing Guidelines 42 | Please refer [CONTRIBUTING.md](https://github.com/namankhurpia/Easy-open-ai/blob/main/CONTRIBUTING.md) 43 | 44 | 45 | # Running guidelines 46 | All "OPENAI_KEYS" must be read through the readKeys() function defined [here](https://github.com/namankhurpia/Easy-open-ai/blob/main/src/main/java/io/github/namankhurpia/Documentation/RunnerForSingleInstance.java), this function allows you to read multiple keys at the same time, and for multithreaded task it is adviced to use multiple keys to avoid rate limiting. To run this function you need to have keys.txt in your project root folder (feel free to edit). 47 | 48 | 49 | # Usage - syntax 50 | 51 | ## Chat Completion API 52 | 53 | To use the Chat Completion API, follow these steps: 54 | 55 | ```java 56 | 57 | Message message = Message.builder() 58 | .role("user") 59 | .content("what is the capital of Cambodia?") 60 | .build(); 61 | 62 | List messages = new ArrayList<>(); 63 | messages.add(message); 64 | 65 | ChatCompletionRequest request = ChatCompletionRequest.builder() 66 | .model("gpt-3.5-turbo") 67 | .messages(messages) 68 | .build(); 69 | 70 | ChatCompletionResponse response = new EasyopenaiService(new DAOImpl()).chatCompletion("OPENAI_KEY",request); 71 | 72 | ``` 73 | 74 | Click [here](https://github.com/namankhurpia/Easy-open-ai/blob/main/src/main/java/io/github/namankhurpia/Documentation/RunnerForSingleInstance.java) to jump to the code example. 75 | 76 | ## Moderation API 77 | 78 | ### Single Request, Single Response 79 | 80 | To use the Moderation API, follow these steps: 81 | 82 | ```java 83 | 84 | ModerationAPIRequest request = ModerationAPIRequest.builder() 85 | .model("text-moderation-latest") 86 | .input("hello from the other side kill me now") 87 | .build(); 88 | 89 | ModerationAPIResponse res = new EasyopenaiService(new DAOImpl()).getmoderation("OPENAI_KEY",request); 90 | ``` 91 | 92 | Click [here](https://github.com/namankhurpia/Easy-open-ai/blob/main/src/main/java/io/github/namankhurpia/Documentation/RunnerForSingleInstance.java) to jump to the code example. 93 | 94 | ## Easy Vision API 95 | 96 | Vision API can be used like this, feel free to add N number of images in list of Images- 97 | 98 | ```java 99 | VisionApiResponse responseobj = new EasyVisionService().VisionAPI("OPENAI_KEY", new EasyVisionRequest() 100 | .setModel("gpt-4-vision-preview") 101 | .setPrompt("What are the difference between these images?") 102 | .setImageUrls(new ArrayList() {{ 103 | add("https://images.pexels.com/photos/268533/pexels-photo-268533.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1"); 104 | add("https://images.pexels.com/photos/36717/amazing-animal-beautiful-beautifull.jpg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1"); 105 | }})); 106 | ``` 107 | 108 | ```java 109 | .setMaxtokens(1000) //Optional - for more tokens, defaults to 300 110 | ``` 111 | 112 | Click [here](https://github.com/namankhurpia/Easy-open-ai/blob/main/src/main/java/io/github/namankhurpia/Documentation/RunnerForSingleInstance.java) to jump to the code example. 113 | 114 | 115 | ## Vision API 116 | 117 | To use the Vision API, follow these steps: 118 | 119 | 1. Initialize the EasyopenaiService object with an instance of DAOImpl: 120 | 121 | 122 | ```java 123 | EasyopenaiService obj = new EasyopenaiService(new DAOImpl()); 124 | ``` 125 | 126 | 2. Create a VisionApiRequest object: 127 | 128 | 129 | ```java 130 | VisionApiRequest request = new VisionApiRequest(); 131 | ``` 132 | 3. Create an ImageUrl object with the image URL and detail: 133 | 134 | 135 | ```java 136 | ImageUrl url = new ImageUrl(); 137 | url.setUrl("https://images.pexels.com/photos/18907092/pexels-photo-18907092/free-photo-of-a-photo-of-the-golden-gate-bridge-in-the-sky.jpeg"); 138 | url.setDetail("low"); 139 | ``` 140 | 4. Create a list of Content objects to represent the messages: 141 | 142 | 143 | ```java 144 | Content content1 = new Content(); 145 | content1.setText("What’s in this image?"); 146 | content1.setType("text"); 147 | 148 | Content content2 = new Content(); 149 | content2.setImageUrl(url); 150 | content2.setType("image_url"); 151 | 152 | ArrayList listofContent = new ArrayList<>(); 153 | listofContent.add(content1); 154 | listofContent.add(content2); 155 | ``` 156 | 5. Create a MessageList object with the role ("user") and the list of content: 157 | 158 | 159 | ```java 160 | MessageList messageList = new MessageList(); 161 | messageList.setRole("user"); 162 | messageList.setContent(listofContent); 163 | ``` 164 | 6. Create a list of MessageList objects: 165 | 166 | 167 | ```java 168 | ArrayList listofMessage = new ArrayList<>(); 169 | listofMessage.add(messageList); 170 | ``` 171 | 7. Set various properties of the VisionApiRequest object: 172 | 173 | 174 | ```java 175 | request.setModel("gpt-4-vision-preview"); 176 | request.setMaxTokens(300); 177 | request.setMessages(listofMessage); 178 | ``` 179 | 8. Make the API call and Print Response: 180 | 181 | 182 | ```java 183 | VisionApiResponse res = obj.visionAPI(OPENAI_KEY, request); 184 | System.out.println("Vision API Response is:" + res); 185 | ``` 186 | 187 | Click [here](https://github.com/namankhurpia/Easy-open-ai/blob/main/src/main/java/io/github/namankhurpia/Documentation/RunnerForSingleInstance.java) to jump to the code example. 188 | 189 | ## Speech API 190 | Speech API can be used like this, feel free to tweak- 191 | 192 | ```java 193 | SpeechRequest request = SpeechRequest.builder() 194 | .model("tts-1") 195 | .input("Easy OpenAI is best solution.") 196 | .voice("alloy") 197 | .build(); 198 | 199 | ResponseBody response = new EasyopenaiService(new DAOImpl()).createSpeech("OPENAI_KEY",request); 200 | 201 | ``` 202 | Click [here](https://github.com/namankhurpia/Easy-open-ai/blob/main/src/main/java/io/github/namankhurpia/Documentation/RunnerForSingleInstance.java) to jump to the code example. 203 | 204 | 205 | ## Easy Transcription API 206 | 207 | Transcription API can be used like this, feel free to tweak- 208 | 209 | ```java 210 | EasyTranscriptionRequest request = EasyTranscriptionRequest.builder() 211 | .filepath("/Users/namankhurpia/Desktop/audio.mp3") 212 | .model("whisper-1") 213 | .build(); 214 | 215 | ResponseBody response = new EasyTranscriptionService().EasyTranscription("OPENAI_KEY", request); 216 | ``` 217 | 218 | Click [here](https://github.com/namankhurpia/Easy-open-ai/blob/main/src/main/java/io/github/namankhurpia/Documentation/RunnerForSingleInstance.java) to jump to the code example. 219 | 220 | 221 | ## Transcription API 222 | 223 | ### Original Transcription API by OpenAI 224 | Transcription API can be used like this, feel free to tweak- 225 | 226 | 227 | ```java 228 | File audioFile = new File("/Users/namankhurpia/Desktop/audio.mp3"); 229 | MultipartBody.Part filePart = MultipartBody.Part.createFormData( 230 | "file", 231 | audioFile.getName(), 232 | RequestBody.create(MediaType.parse("audio/*"), audioFile) 233 | ); 234 | 235 | RequestBody model = RequestBody.create(MediaType.parse("text/plain"), "whisper-1"); 236 | RequestBody language = RequestBody.create(MediaType.parse("text/plain"), ""); 237 | RequestBody prompt = RequestBody.create(MediaType.parse("text/plain"), ""); 238 | RequestBody response_format = RequestBody.create(MediaType.parse("text/plain"), ""); 239 | RequestBody temperature = RequestBody.create(MediaType.parse("text/plain"), ""); 240 | 241 | ResponseBody response = new EasyopenaiService(new DAOImpl()).createTranscriptions("OPENAI_KEY", filePart,model, language,prompt,response_format,temperature); 242 | ``` 243 | 244 | Click [here](https://github.com/namankhurpia/Easy-open-ai/blob/main/src/main/java/io/github/namankhurpia/Documentation/RunnerForSingleInstance.java) to jump to the code example. 245 | 246 | 247 | ## Image Generation API 248 | 249 | Image Generation API can be used like this, feel free to tweak- 250 | 251 | ```java 252 | ImageRequest imageRequest = ImageRequest.builder() 253 | .prompt("Generate a cute dog playing with frizbee") 254 | .model("dall-e-2") 255 | .build(); 256 | 257 | ImageResponse response = new EasyopenaiService(new DAOImpl()).createImage("OPENAI_KEY",imageRequest); 258 | ``` 259 | Click [here](https://github.com/namankhurpia/Easy-open-ai/blob/main/src/main/java/io/github/namankhurpia/Documentation/RunnerForSingleInstance.java) to jump to the code example. 260 | 261 | 262 | ## Async Chat Completion API 263 | 264 | To use the Chat Completion API asynchronously, follow these steps: 265 | 266 | 1. Initialize the `EasyopenaiAsyncService` object with an instance of `AsyncDAOImpl`: 267 | 268 | ```java 269 | EasyopenaiAsyncService obj = new EasyopenaiAsyncService(new AsyncDAOImpl()); 270 | ``` 271 | 272 | 2. Create a list of `ChatMessage` objects to represent the conversation: 273 | 274 | ```java 275 | ChatMessage message = new ChatMessage(); 276 | message.setRole("user"); 277 | message.setContent("what is the capital of Cambodia?"); 278 | 279 | List messages = new ArrayList<>(); 280 | messages.add(message); 281 | ``` 282 | 283 | 3. Create a `ChatCompletionRequest` object: 284 | 285 | ```java 286 | ChatCompletionRequest request = new ChatCompletionRequest(); 287 | request.setModel("gpt-3.5-turbo"); 288 | request.setMessages(messages); // old conversations as well 289 | ``` 290 | 291 | 4. Make the asynchronous API call: 292 | 293 | ```java 294 | ChatCompletionResponse res = obj.getAsyncChatCompletion(OPENAI_KEY, request); 295 | ``` 296 | 297 | Click [here](#async-chat-completion-api) to jump to the code example. 298 | 299 | ## Async Moderation API 300 | 301 | To use the Moderation API asynchronously, follow these steps: 302 | 303 | 1. Create a `ModerationAPIRequest` object: 304 | 305 | ```java 306 | ModerationAPIRequest request = new ModerationAPIRequest(); 307 | request.setInput("kill me now"); 308 | request.setModel("text-moderation-latest"); 309 | ``` 310 | 311 | 2. Initialize the `EasyopenaiAsyncService` object with an instance of `AsyncDAOImpl`: 312 | 313 | ```java 314 | EasyopenaiAsyncService obj = new EasyopenaiAsyncService(new AsyncDAOImpl()); 315 | ``` 316 | 317 | 3. Make the asynchronous API call: 318 | 319 | ```java 320 | ModerationAPIResponse res = obj.getASyncModeration(OPENAI_KEY, request); 321 | ``` 322 | 323 | Click [here](#async-moderation-api) to jump to the code example. 324 | 325 | 326 | 327 | 328 | ## Multithreaded Async Chat Completion API 329 | 330 | For multi-threading and concurrent calls with Chat Completion API, follow these steps: 331 | 332 | 1. Create a `ChatCompletionRequestList` object: 333 | 334 | ```java 335 | ChatCompletionRequestList list = new ChatCompletionRequestList(new ArrayList()); 336 | ``` 337 | 338 | 2. Add multiple `ChatCompletionRequest` objects to the list: 339 | 340 | ```java 341 | // Example request 1 342 | ChatCompletionRequest requestchat = new ChatCompletionRequest(); 343 | requestchat.setModel("gpt-3.5-turbo"); 344 | ChatMessage message = new ChatMessage(); 345 | message.setRole("user"); 346 | message.setContent("what is the capital of India?"); 347 | List messages = new ArrayList<>(); 348 | messages.add(message); 349 | requestchat.setMessages(messages); 350 | list.add(requestchat); 351 | 352 | // Add more requests as needed (requestchat2, requestchat3, requestchat4, etc.) 353 | ``` 354 | 355 | 3. Make the multi-asynchronous API call: 356 | 357 | ```java 358 | EasyopenaiConcurrentService concurrentCalls = new EasyopenaiConcurrentService(); 359 | ChatCompletionResponseList responseList = concurrentCalls.CallMultipleChatCompletionAPI(OPENAI_KEY, list); 360 | System.out.println(responseList); 361 | ``` 362 | 363 | Click [here](#multi-async-chat-completion-api) to jump to the code example. 364 | 365 | ## Multithreaded Async Moderation API 366 | 367 | For multi-threading and concurrent calls with the Moderation API, follow these steps: 368 | 369 | 1. Create a `ModerationRequestList` object: 370 | 371 | ```java 372 | ModerationRequestList requestList = new ModerationRequestList(new ArrayList()); 373 | ``` 374 | 375 | 2. Add multiple `ModerationAPIRequest` objects to the list: 376 | 377 | ```java 378 | // Example request 1 379 | ModerationAPIRequest request = new ModerationAPIRequest(); 380 | request.setInput("kill me now"); 381 | request.setModel("text-moderation-latest"); 382 | requestList.add(request); 383 | 384 | // Add more requests as needed (request2, request3, request4, etc.) 385 | ``` 386 | 387 | 3. Make the multi-asynchronous API call: 388 | 389 | ```java 390 | EasyopenaiConcurrentService concurrentCalls = new EasyopenaiConcurrentService(); 391 | ModerationResponseList responseList = concurrentCalls.CallMultipleModerationAPI(OPENAI_KEY, requestList); 392 | System.out.println(responseList); 393 | ``` 394 | 395 | Click [here](#multi-async-moderation-api) to jump to the code example. 396 | 397 | ## EMMC EasyOpenAI Multithreaded MultiKey ChatCompletionAPI 398 | 399 | This allows you to make multiple Chat completion calls with multiple keys. All API calls are executed parallely but the response is actively collected and sent back when all the threads are finished. 400 | 401 | CompletableFuture class has been used for implementation. Kindly refer EasyopenaiConcurrentService.java file to see the source. 402 | 403 | Example Usgage- 404 | 405 | ```java 406 | public static void CallMultipleChatCompletionAPI_multikey_Test() 407 | { 408 | //this function read multiple keys from keys.txt file 409 | ArrayList keyList = readKeys(); 410 | 411 | EasyopenaiConcurrentService concurrentCalls = new EasyopenaiConcurrentService(); 412 | 413 | ChatCompletionRequestList list = new ChatCompletionRequestList(new ArrayList()); 414 | 415 | //First thread for 416 | ChatCompletionRequest requestchat = new ChatCompletionRequest(); 417 | requestchat.setModel("gpt-3.5-turbo"); 418 | Message message = new Message(); 419 | message.setRole("user"); 420 | message.setContent("what is the capital of India?"); 421 | List messages = new ArrayList<>(); 422 | messages.add(message); 423 | requestchat.setMessages(messages); 424 | list.add(requestchat); 425 | 426 | 427 | ChatCompletionRequest requestchat2 = new ChatCompletionRequest(); 428 | requestchat2.setModel("gpt-3.5-turbo"); 429 | Message message2 = new Message(); 430 | message2.setRole("user"); 431 | message2.setContent("what is the capital of combodia?"); 432 | List messages2 = new ArrayList<>(); 433 | messages2.add(message2); 434 | requestchat2.setMessages(messages2); 435 | list.add(requestchat2); 436 | 437 | 438 | ChatCompletionRequest requestchat3 = new ChatCompletionRequest(); 439 | requestchat3.setModel("gpt-3.5-turbo"); 440 | Message message3 = new Message(); 441 | message3.setRole("user"); 442 | message3.setContent("what is the capital of new zealand?"); 443 | List messages3 = new ArrayList<>(); 444 | messages3.add(message3); 445 | requestchat3.setMessages(messages3); 446 | list.add(requestchat3); 447 | 448 | 449 | ChatCompletionRequest requestchat4 = new ChatCompletionRequest(); 450 | requestchat4.setModel("gpt-3.5-turbo"); 451 | Message message4 = new Message(); 452 | message4.setRole("user"); 453 | message4.setContent("what is the capital of hawaii? and what is 2+2?"); 454 | List messages4 = new ArrayList<>(); 455 | messages4.add(message4); 456 | requestchat4.setMessages(messages4); 457 | list.add(requestchat4); 458 | 459 | 460 | 461 | ChatCompletionResponseList responseList = concurrentCalls.CallMultipleChatCompletionAPI(keyList, list); 462 | System.out.println("response is"+responseList); 463 | } 464 | ``` 465 | 466 | # Dependencies 467 | 468 | Ensure you have the required dependencies installed before using the OpenAI API wrapper. 469 | 470 | 471 | ## Maven 472 | 473 | ```xml 474 | 475 | io.github.namankhurpia 476 | easyopenai 477 | x.x.x 478 | 479 | ``` 480 | 481 | ## Groovy - Gradle 482 | ``` 483 | implementation group: 'io.github.namankhurpia', name: 'easyopenai', version: 'x.x.x' 484 | ``` 485 | 486 | ## Gradle Java - 487 | ``` 488 | implementation 'io.github.namankhurpia:easyopenai:x.x.x' 489 | ``` 490 | ## Gradle Kotlin- 491 | ``` 492 | implementation("io.github.namankhurpia:easyopenai:x.x.x") 493 | ``` 494 | ## SBT - 495 | ``` 496 | libraryDependencies += "io.github.namankhurpia" % "easyopenai" % "x.x.x" 497 | ``` 498 | ## Ivy- 499 | ``` 500 | 501 | ``` 502 | ## Grape- 503 | ``` 504 | @Grapes( 505 | @Grab(group='io.github.namankhurpia', module='easyopenai', version='x.x.x') 506 | ) 507 | ``` 508 | ## Leiningen 509 | ``` 510 | [io.github.namankhurpia/easyopenai "x.x.x"] 511 | ``` 512 | ## Buildr 513 | ``` 514 | 'io.github.namankhurpia:easyopenai:jar:x.x.x' 515 | ``` --------------------------------------------------------------------------------