OpenAI/ChatGPT library for Java - Requires JDK 11 at minimum.
APACHE-2.0 License
Note, this project is under active development. If there are any suggestions you may have, feel free to let me know.
You can use this library as part of your project & integrate it into your app.
OpenAI is free-to-use, but you will require an API key. You can get this for free by clicking here.
OpenAI openAI = OpenAI.builder()
.setApiKey("YOUR_API_KEY_HERE") //Required
.setOrganization("YOUR_ORGANIZATION_HERE") //Optional
.createChatCompletion(chatMessageHistoryHere) //Optional (ChatGPT)
.setTimeout(Duration.ofSeconds(10)) //Optional
.setProxy(proxy) //Optional
.build() //Creates our OpenAI class from our OpenAI.Builder
.sendRequest(); //Optional - Sends request to OpenAI
1.1.2
The dependencies I am using for this project are
jackson-databind
for JSON parsing,junit-jupiter
for testing andjacoco
for reporting.
<dependency>
<groupId>io.github.jetkai</groupId>
<artifactId>openai</artifactId>
<version>1.1.2</version>
</dependency>
//Groovy (build.gradle)
implementation group: 'io.github.jetkai', name: 'openai', version: '1.1.2'
//Kotlin (build.gradle.kts)
implementation("io.github.jetkai:openai:1.1.2")
Binary (Recommended)
|
Binary (Excluding Dependencies)
|
JavaDoc | Sources |
---|---|---|---|
> Download < | > Download < | > Download < | > Download < |
March 2023
ChatGPT 3.5 (Latest) - using CreateChatCompletion
Spell Checking - using CreateCompletion
Transcriptions (From Audio File) - using CreateTranscription
Translations (From Text or Audio File) - using CreateTranslation
/ CreateTranscriptionTranslation
AI Image Creation / Editing - using CreateImage
/ CreateImageEdit
/ CreateImageVariation
https://api.openai.com/v1/models
https://api.openai.com/v1/models/{model}
https://api.openai.com/v1/completions
https://api.openai.com/v1/chat/completions
https://api.openai.com/v1/edits
https://api.openai.com/v1/images/generations
https://api.openai.com/v1/images/edits
https://api.openai.com/v1/images/variations
https://api.openai.com/v1/embeddings
https://api.openai.com/v1/audio/transcriptions
https://api.openai.com/v1/audio/translations
https://api.openai.com/v1/completions
Scenario: Say "Hello" to the AI and ask the AI to respond back with the last thing I said.
public static void main(String[] args) {
ExampleChatGPT gpt = new ExampleChatGPT();
//The first message that we want to send
String message1 = "Hello ChatGPT!";
//The second message that we want to send
String message2 = "What was the first thing I said?";
//Response 1 from ChatGPT
String response1 = gpt.exampleBuilders(message1);
System.out.println("Sent: " + message1);
System.out.println("Response: " + response1);
//Response 2 from ChatGPT
String response2 = gpt.exampleBuilders(message2);
System.out.println("Sent: " + message2);
System.out.println("Response: " + response2);
}
private String exampleBuilders(String message) {
//Create the Message Data object with the message we wish to send
ChatCompletionMessageData messageData = ChatCompletionMessageData.builder()
.setRole("user")
.setContent(message)
.build();
//Store the message that we want to send, to the MessageHistory List
messageHistory.add(messageData);
//Build the data structure which contains the message history and model information
ChatCompletionData completionData = ChatCompletionData.builder()
.setModel("gpt-3.5-turbo")
.setMessages(messageHistory)
.build();
//Sends the request to OpenAI's endpoint & parses the response data
//Instead of openAI.sendRequest(); you can initialize the request
//for the class manually - openAI.createChatCompletion().initialize();
OpenAI openAI = OpenAI.builder()
.setApiKey(System.getenv("OPEN_AI_API_KEY"))
.createChatCompletion(completionData)
.build()
.sendRequest();
//Check to see if there is a valid response from OpenAI
//You can also call Optional<CreateChatCompletion> createChatCompletion = openAI.chatCompletion();
CreateChatCompletion createChatCompletion = openAI.getChatCompletion();
//Store chat response from AI, this allows the AI to see the full history of our chat
//Including both our messages and the AI's messages
messageHistory.addAll(createChatCompletion.asChatResponseDataList());
//Parse the response back as plain-text & replace \n & ascii characters ( -> String)
return createChatCompletion.asNormalizedText();
}
Scenario: Have an AI create a red panda with glasses, and have this drawn as a cartoon.
public static void main(String[] args) throws IOException {
//Initialize ExampleImageCreation class
ExampleImageCreation imageCreation = new ExampleImageCreation();
//A text description of the desired image(s). The maximum length is 1000 characters
String description = "A picture of a red panda with glasses, drawn as a cartoon.";
//The number of images to generate. Must be between 1 and 10.
int amount = 1;
//The size of the generated images. Must be one of 256x256, 512x512, or 1024x1024
String size = "1024x1024";
URI[] imageLinks = imageCreation.communicate(description, amount, size);
for(URI imageLink : imageLinks) {
System.out.println("Opening URI ["+imageLink+"] in the web browser.");
Desktop.getDesktop().browse(imageLink);
}
}
private URI[] communicate(String imageDescription, int numberOfImages, String size) {
//Alternatively can use ImageData.create(imageDescription, numberOfImages, size);
ImageData imageData = ImageData.builder()
//A text description of the desired image(s). The maximum length is 1000 characters
.setPrompt(imageDescription)
//The number of images to generate. Must be between 1 and 10.
.setN(numberOfImages)
//The size of the generated images. Must be one of 256x256, 512x512, or 1024x1024
.setSize(size)
.build();
OpenAI openAI = OpenAI.builder()
//Set our OpenAI API key
.setApiKey(System.getenv("OPEN_AI_API_KEY"))
//Specify the createImage API endpoint
.createImage(imageData)
.build()
//Sends the request to OpenAI's endpoint & parses the response data
.sendRequest();
//Call the CreateImage API from OpenAI & create instance
Optional<CreateImage> createImage = openAI.image();
//Gather the URI(s) from the API response
return createImage.map(CreateImage::asUriArray).orElse(null);
}
Scenario: Correct the spelling within the sentence "Wha dai of the wek is it?".
public static void main(String[] args) {
//Initialize ExampleSpellingCorrection class
ExampleSpellingCorrection spelling = new ExampleSpellingCorrection();
String spellingMistake = "Wha dai of the wek is it?";
String instruction = "Fix the spelling mistakes";
//Send request to API - response as string
String spellingCorrection = spelling.communicate(spellingMistake, instruction);
//Print out the mistake & correction
System.out.println("Mistake: " + spellingMistake);
System.out.println("Correction: " + spellingCorrection);
}
private String communicate(String spellingMistake, String instruction) {
//Call the ListModels API from OpenAI & create instance
//You can also specify the model and use the following:
//EditData.create(model, spellingMistake, instruction);
EditData editData = EditData.create(spellingMistake, instruction);
OpenAI openAI = OpenAI.builder()
.setApiKey(System.getenv("OPEN_AI_API_KEY"))
.createEdit(editData)
.build()
//Sends the request to OpenAI's endpoint & parses the response data
.sendRequest();
//Call the CreateEdit API from OpenAI & create instance
Optional<CreateEdit> createEdit = openAI.edit();
//Return model as a JSON string
return createEdit.map(CreateEdit::asText).orElse(null);
}
Scenario: Translate "Hello, how are you today?" from English to French.
public static void main(String[] args) {
//Initialize ExampleTranslation class
ExampleTranslation translation = new ExampleTranslation();
//This is the language we want to translate our audio file to
String toLanguage = "French";
//Example audio file that we are going to upload to OpenAI to be translated
String message = "Hello, how are you today?";
//Response from OpenAI with the translated string
String response = translation.communicate(message, toLanguage);
//Print the translation to the console
System.out.println(response);
}
private String communicate(String message, String toLanguage) {
//TranslationData, ready to send to the OpenAI API
CompletionData translationData = CompletionData.translation(message, toLanguage);
OpenAI openAI = OpenAI.builder()
.setApiKey(System.getenv("OPEN_AI_API_KEY"))
.createTranslation(translationData)
.build()
//Sends the request to OpenAI's endpoint & parses the response data
.sendRequest();
//Call the CreateTranslation API from OpenAI & create instance
Optional<CreateTranslation> createTranslation = openAI.translation();
//Return as text, do not replace \n or ascii characters
return createTranslation.map(CreateCompletion::asText).orElse(null);
}
Scenario: Create a transcript from an audio file.
public static void main(String[] args) throws URISyntaxException {
//Initialize ExampleTranslationFromAudioFile class
ExampleTranscriptionFromAudioFile transcriptAudioFile = new ExampleTranscriptionFromAudioFile();
//Example audio file that we are going to upload to OpenAI to be translated
URL audioUrl = ExampleTranscriptionFromAudioFile.class.getResource("what-can-i-do.mp3");
Path filePath = null;
if (audioUrl != null) {
filePath = Path.of(audioUrl.toURI());
}
//Response from OpenAI with the translated string
String response = transcriptAudioFile.communicate(filePath);
//Print the translation to the console
System.out.println(response);
}
private String communicate(Path filePath) {
//AudioData, ready to send to the OpenAI API
AudioData transcriptionData = AudioData.create(filePath);
OpenAI openAI = OpenAI.builder()
.setApiKey(System.getenv("OPEN_AI_API_KEY"))
.createTranscription(transcriptionData)
.build()
//Sends the request to OpenAI's endpoint & parses the response data
.sendRequest();
//Call the CreateTranscription API from OpenAI & create instance
Optional<CreateTranscription> createTranscription = openAI.transcription();
//Return as text, do not replace \n or ascii characters
return createTranscription.map(CreateTranscription::asText).orElse(null);
}
Scenario: Create a transcript from an audio file, then translate the transcript from English to French.
public static void main(String[] args) throws URISyntaxException {
//Initialize ExampleTranslationFromAudioFile class
ExampleTranslationFromAudioFile translateFromAudioFile = new ExampleTranslationFromAudioFile();
//This is the language we want to translate our audio file to
//Language parameter must be specified in ISO-639-1 format or Locale
//Example -> "French" = "fr" | "English UK" = "en_GB"
//String language = "fr";
Locale language = Locale.FRENCH;
//Example audio file that we are going to upload to OpenAI to be translated
URL audioUrl = ExampleTranslationFromAudioFile.class.getResource("what-can-i-do.mp3");
Path filePath = null;
if (audioUrl != null) {
filePath = Path.of(audioUrl.toURI());
}
if(filePath == null) {
System.err.println("File could not be found.");
return;
}
//Response from OpenAI with the translated string
String response = translateFromAudioFile.communicate(filePath, language);
//Print the translation to the console
System.out.println(response);
}
private String communicate(Path filePath, Locale language) {
//Alternatively can use AudioData.create(audioPath, "fr");
AudioData audioTranslationData = AudioData.create(filePath, language);
OpenAI openAI = OpenAI.builder()
.setApiKey(System.getenv("OPEN_AI_API_KEY"))
.createTranscriptionTranslation(audioTranslationData)
.build();
//Sends the request to OpenAI's endpoint & parses the response data
openAI.sendRequest();
//Call the CreateTranslation API from OpenAI & create instance
Optional<CreateTranscriptionTranslation> createTranslation = openAI.transcriptionTranslation();
//Return as text, do not replace \n or ascii characters
return createTranslation.map(CreateTranscription::asText).orElse(null);
}
Scenario: Get information about a specific model.
public static void main(String[] args) {
//Initialize ExampleListModel class
ExampleListModel getModel = new ExampleListModel();
//Send request to API - response as JSON string
String modelJson = getModel.communicate();
//Print out the model information in JSON
System.out.println(modelJson);
}
private String communicate() {
String modelName = "davinci";
OpenAI openAI = OpenAI.builder()
.setApiKey(System.getenv("OPEN_AI_API_KEY"))
.listModel(modelName)
.build()
//Sends the request to OpenAI's endpoint & parses the response data
.sendRequest();
//Call the ListModels API from OpenAI & create instance
Optional<ListModel> getModels = openAI.model();
//Return model as a JSON string
return getModels.map(ListModel::asJson).orElse(null);
}
Scenario: List all the models available from OpenAI.
public static void main(String[] args) {
//Initialize ExampleListModels class
ExampleListModels getModels = new ExampleListModels();
//Send request to API and deserialize response as List<ModalData>
List<ModelData> models = getModels.communicate();
for(ModelData model : models) {
Optional<String> id = model.id();
if(id.isEmpty()) {
continue;
}
//Print out the names of all the available models, to the console
System.out.println(id.get());
}
//models.stream().map(ModelData::id).forEach(System.out::println);
}
private List<ModelData> communicate() {
OpenAI openAI = OpenAI.builder()
.setApiKey(System.getenv("OPEN_AI_API_KEY"))
.listModels()
.build()
//Sends the request to OpenAI's endpoint & parses the response data
.sendRequest();
//Call the ListModels API from OpenAI & create instance
Optional<ListModels> getModels = openAI.models();
//Return models as a data structure list, so that we can get the name from each model
return getModels.map(ListModels::asDataList).orElse(null);
}
@Test
void createCompletionTest() {
//Grab OpenAI API key from system environment variables (gradle.properties)
String apiKey = System.getenv("OPEN_AI_API_KEY");
String organization = System.getenv("OPEN_AI_ORGANIZATION");
assertNotNull(apiKey);
assertNotNull(organization);
//CompletionData, ready to send to the OpenAI API
CompletionData completion = CompletionData.builder()
//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.
.setModel("text-davinci-003")
//The prompt(s) to generate completions for, encoded as a string, array of strings, array of tokens,
//or array of token arrays.
//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.
.setPrompt("Say this is a test")
//The maximum number of tokens to generate in the completion.
//The token count of your prompt plus max_tokens cannot exceed the model's context length.
//Most models have a context length of 2048 tokens (except for the newest models, which support 4096).
.setMaxTokens(7)
//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.
//We generally recommend altering this or top_p but not both.
.setTemperature(0)
//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.
//We generally recommend altering this or temperature but not both.
.setTopP(1)
//How many completions to generate for each prompt.
//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.
.setN(1)
//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.
.setStream(false)
//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.
//The maximum value for logprobs is 5. If you need more than this, please contact us through our
//Help center and describe your use case.
//.setLogprobs()
//Up to 4 sequences where the API will stop generating further tokens.
//The returned text will not contain the stop sequence.
.setStop("\n")
.build();
//Create OpenAI instance using API key & organization
//Organization is optional
OpenAI openAI = OpenAI.builder()
.setApiKey(apiKey)
.setOrganization(organization)
.createCompletion(completion)
.build()
.sendRequest();
assertNotNull(openAI);
//Call the CreateCompletion API from OpenAI & create instance
Optional<CreateCompletion> optionalCreateCompletion = openAI.completion();
assertFalse(optionalCreateCompletion.isEmpty());
CreateCompletion createCompletion = optionalCreateCompletion.get();
//Data structure example
CompletionResponseData responseData = createCompletion.asData();
assertNotNull(responseData);
//Json example
String json = createCompletion.asJson();
assertNotNull(json);
assertFalse(json.isEmpty());
}
@Test
void createEditTest() {
//Grab OpenAI API key from system environment variables (gradle.properties)
String apiKey = System.getenv("OPEN_AI_API_KEY");
String organization = System.getenv("OPEN_AI_ORGANIZATION");
assertNotNull(apiKey);
assertNotNull(organization);
//EditData, ready to send to the OpenAI Api
EditData edit = EditData.builder()
//ID of the model to use. You can use the text-davinci-edit-001 or
//code-davinci-edit-001 model with this endpoint.
.setModel("text-davinci-edit-001")
//The input text to use as a starting point for the edit.
.setInput("What day of the wek is it?")
//The instruction that tells the model how to edit the prompt.
.setInstruction("Fix the spelling mistakes")
.build();
//Create OpenAI instance using API key & organization
//Organization is optional
OpenAI openAI = OpenAI.builder()
.setApiKey(apiKey)
.setOrganization(organization)
.createEdit(edit)
.build()
.sendRequest();
assertNotNull(openAI);
//Call the CreateEdit API from OpenAI & create instance
Optional<CreateEdit> optionalCreateEdit = openAI.edit(); //You can call "data" to see the response
assertFalse(optionalCreateEdit.isEmpty());
CreateEdit createEdit = optionalCreateEdit.get();
//Data structure example
CompletionResponseData responseData = createEdit.asData();
assertNotNull(responseData);
//StringArray example
String[] stringArray = createEdit.asStringArray();
assertNotNull(stringArray);
//Json example
String json = createEdit.asJson();
assertNotNull(json);
assertFalse(json.isEmpty());
}
@Test
void createImageVariationTest() {
//Grab OpenAI API key from system environment variables (gradle.properties)
String apiKey = System.getenv("OPEN_AI_API_KEY");
String organization = System.getenv("OPEN_AI_ORGANIZATION");
assertNotNull(apiKey);
assertNotNull(organization);
//Example image file that we are going to upload to OpenAI
URL imageUrl = CreateImageVariationTest.class.getResource("otter.png");
Path imagePath = null;
try {
if (imageUrl != null) {
imagePath = Path.of(imageUrl.toURI());
}
} catch (URISyntaxException e) {
throw new RuntimeException(e);
}
assertNotNull(imagePath);
//ImageVariationData, ready to send to the OpenAI API
ImageVariationData imageVariationData = ImageVariationData.builder()
//Set the path for the image file
.setImage(imagePath)
//Set the number of images to generate. Must be between 1 and 10.
.setN(2)
//Set the size of the generated images. Must be one of 256x256, 512x512, or 1024x1024.
.setSize("256x256")
.build();
//Create OpenAI instance using API key & organization
//Organization is optional
OpenAI openAI = OpenAI.builder()
.setApiKey(apiKey)
.setOrganization(organization)
.createImageVariation(imageVariationData)
.build()
//Finally, send our request to the API, this initiates the request (after .build())
.sendRequest();
//Call the CreateTranscription API from OpenAI & create instance
Optional<CreateImageVariation> optionalCreateImageVariation = openAI.imageVariation();
assertFalse(optionalCreateImageVariation.isEmpty());
CreateImageVariation createImageVariation = optionalCreateImageVariation.get();
//String List example (contains all the image urls)
List<String> stringList = createImageVariation.asStringList();
assertNotNull(stringList);
assertFalse(stringList.isEmpty());
//URI array example (contains all the image urls)
URI[] uriArray = createImageVariation.asUriArray();
assertNotNull(uriArray);
assertNotEquals(0, uriArray.length);
//Data structure example
ImageResponseData responseData = createImageVariation.asData();
assertNotNull(responseData);
//Json example
String json = createImageVariation.asJson();
assertNotNull(json);
assertFalse(json.isEmpty());
}
@Test
void createEmbeddingTest() {
//Grab OpenAI API key from system environment variables (gradle.properties)
String apiKey = System.getenv("OPEN_AI_API_KEY");
String organization = System.getenv("OPEN_AI_ORGANIZATION");
assertNotNull(apiKey);
assertNotNull(organization);
//EmbeddingData, ready to send to the OpenAI API
EmbeddingData embed = EmbeddingData.builder()
//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.
.setModel("text-embedding-ada-002")
//Input text to get embeddings for, encoded as a string or array of tokens.
//To get embeddings for multiple inputs in a single request, pass an array of strings or array of token arrays.
//Each input must not exceed 8192 tokens in length.
.setInput("The food was delicious and the waiter...")
.build();
//Call the CreateEmbedding API from OpenAI & create instance
OpenAI openAI = OpenAI.builder()
.setApiKey(apiKey)
.setOrganization(organization)
.createEmbedding(embed)
.build()
.sendRequest();
Optional<CreateEmbedding> optionalEmbedding = openAI.embedding();
assertFalse(optionalEmbedding.isEmpty());
CreateEmbedding createEmbedding = optionalEmbedding.get();
//Data structure example
EmbeddingResponseData embeddingBlock = createEmbedding.asData();
assertNotNull(embeddingBlock);
//Float List example
List<Float> floatList = createEmbedding.asFloatList();
assertNotNull(floatList);
assertFalse(floatList.isEmpty());
//Json example
String json = createEmbedding.asJson();
assertNotNull(json);
assertFalse(json.isEmpty());
}