We can now officially say it's the 21st century as artifical intelligence (AI) has finally arrived.

And while you're waiting for The Matrix (or SkyNet) to take over, you can start using AI for your own advantage. And for your own financial enrichment.

Enter Microsofit's OpenAI API. That's the beast that powers ChatGPT, which you've probably heard about by now or you wouldn't be reading this article.

But alas, you're probably facing a challenge. You, the notable Java developer, went to the OpenAI website and found that all the coding examples are in Py... Py.... PYTHON!!1!!1!!!

AAAARRRRRGGGGHHHH!!!

So you went to other websites for help and found the same thing. Then you yelled at the clouds again.

And then you came here.

I can show you how to get started with OpenAI and ChatGPT as a professional or not-so-professional Java application engineer.

And I've got code you can hijack as well.

So let's get this thing started.

Accounting Era

Let's focus on getting your account set up first.

Warning: if you want to play with the OpenAI API, you will need to fork over some cash. This isn't my fault. 

The good news, though, is that you can do a whole lot of fiddling around with OpenAI before you even spend 1 red cent. As of this writing, anyway.

But you'll still need to provide a credit card number. Don't shoot the messenger.

Kick things off by visiting this link and clicking Sign Up to set up your account.

Once you've completed that step, login and click on your icon in the upper, right-hand corner, Select Manage account from the dropdown menu that appears.

 

Let me just stop right here and say that by the time you're reading this, Microsoft might have complete changed its user interface such that it looks nothing like the screenshots I'm sharing with you. If you find that's the case, I'm sorry. 

But that's really on Microsoft.

Anyhoo, once you're in Accounts, select Billing and Payment methods from the menu in the left-hand sidebar.

Click on Add payment method.

And that's where you're going to have to pony up the pesos my friend. Once more, with feeling: don't shoot the messenger.

Click that Usage limits link in the right-hand sidebar to set your monthly spending limits.

By the way, I set my limit to $60 (with a $56 soft limit) and I haven't even hit a penny yet with plenty of tinkering around. Feel free to set a limit that suits your budget.

And keep in mind: you're investing in your own education. It could pay off many times over in the future.

You can probably learn a whole lotta AI with a budget of just $10 per month.

The Key to Success

Next, you need a key.

This is a security thing that tells the OpenAI API that you're authorized to use its service. It also tells Microsoft who to bill for the call you're about to make.

So let's go back to that icon in the upper, right-hand corner of your screen and click on View API keys.

On the next screen that appears, go ahead and click that button that says Create new secret key.

Follow the prompts to create a key and remember to copy and paste it somewhere where you can retrieve it later. You will not be able to view it a second time.

Now you're good to go with making an API call to OpenAI. Let's start by doing that with Postman.

The Postman Only Calls Once

Let's get a single call going with Postman.

Keep in mind: it's beyond the scope of this tutorial to show you how to use Postman. Hopefully, if you're any kind of REST API geek, you already know how to use it.

So create a new request in Postman and call it "Standup Comedian."

Yeah, this is going to be fun.

Next, set it to a POST method with the following endpoint: https://api.openai.com/v1/chat/completions

That endpoint, by the way, is the recommended endpoint for quite a bit of what you're going to do with OpenAI.

Now click on the Authorization tab below the URL and select Bearer Token from the Type dropdown. Paste that secret key you created in the last step in the Token field.

Here's a screenshot that covers the last few steps:

Next, click on the Body tab that you up there and paste in the following JSON payload:

{
    "model": "gpt-3.5-turbo",
    "messages": [
        {
            "role": "system",
            "content": "You are a standup comedian like Richard Pryor."
        },
        {
            "role": "user",
            "content": "Explain what life is like in prison."
        }
    ],
    "temperature": 0.6
}

I'll go over some of the specifics in that payload in future sessions. For now, let's just look at a couple of things.

Note the "system" role. It tells the AI to respond to the request as a standup comedian like Richard Pryor. So we're looking for a few good laughs here.

Next, pay attention to the "user" role. That's where you're asking the AI a specific question.

In this case, we're asking the AI to explain what life is like in prison.

But remember, we're asking it to do that as a standup comedian like Richard Pryor. That's the point of the previous role.

Okay, click the pretty blue Send button next to the URL and be prepared to wait. This will be none too fast.

And here's the response I got back:

{
    "id": "chatcmpl-7iT4zksT4G",
    "object": "chat.completion",
    "created": 1690....,
    "model": "gpt-3.5-turbo",
    "choices": [
        {
            "index": 0,
            "message": {
                "role": "assistant",
                "content": "Well, life in prison is a lot like being stuck in a never-ending episode of \"Orange is the New Black\" with less catchy theme music. It's a place where you can find yourself surrounded by people who have made some questionable life choices, and you can't just change the channel.\n\nFirst off, let's talk about the food. Now, I've heard people complain about airplane food, but let me tell you, it's like gourmet cuisine compared to what they serve in prison. I mean, I've heard rumors that the meatloaf is actually just recycled cardboard with some ketchup on top. And don't even get me started on the mystery meat. I swear, they must have a secret department where they genetically engineer animals that nobody has ever heard of before.\n\nAnd speaking of meals, let's talk about the dining experience. Imagine going to a restaurant where the tables are bolted to the floor, the walls are painted a lovely shade of beige, and the ambiance is so lacking that even a dental office waiting room feels like a five-star hotel. Oh, and you better hope you don't have any dietary restrictions because the only gluten-free option you'll find is the air you breathe.\n\nNow, let's address the elephant in the cell block – the company. In prison, you'll meet a colorful cast of characters, from the hardened criminals who could write a book on \"101 Creative Ways to Use a Toothbrush,\" to the white-collar criminals who can't believe they got caught for embezzling but are secretly relieved they don't have to wear a suit anymore. And let's not forget the prison guards, who are like overgrown hall monitors with a chip on their shoulder.\n\nBut hey, it's not all doom and gloom. Prison can be a great place to discover hidden talents. I've heard some amazing prison stories like how one guy became a master painter using only Jolly Ranchers and toilet paper as his medium. And let's not forget the prison workout routines – those guys could give Arnold Schwarzenegger a run for his money with their innovative use of milk cartons and bed sheets.\n\nIn all seriousness, though, life in prison is no laughing matter. It's a place where people are paying their debts to society, and we shouldn't forget that. But hey, if there's one thing we can learn from prison, it's that sometimes, life gives you lemons, and you just have to make questionable prison wine out of it."
            },
            "finish_reason": "stop"
        }
    ],
    "usage": {
        "prompt_tokens": 31,
        "completion_tokens": 503,
        "total_tokens": 534
    }
}

That "content" property is the actual response. The rest is just metadata.

And bear in mind that your response might not look exactly like mine. You can thank the "temperature" property in the request for that. More on that in another session.

If you got a response that looks anything like that, then congratulations. You're up and running with the OpenAI API!

Now, let's do it in Java.

Doing It in Java

The first thing you need is a Java API for the OpenAI API. And you can get that from my main man Theo Kanning.

(Yes, I know that Microsoft has its own Java API. But it's got the Azure brand name slapped on it. And that scares me. I don't want you to get tied down to something married to Azure if you decide to use a different cloud platform.)

So go ahead and create a new project in Eclipse IntelliJ and set it up as a Maven project. Then, import the dependency for the Java API:

<dependency>
  <groupId>com.theokanning.openai-gpt3-java</groupId>
  <artifactId>service</artifactId>
  <version>0.14.0</version>       
</dependency>

And while you're at it, go ahead and add some logging support as well.

<dependency>
  <groupId>ch.qos.logback</groupId>
  <artifactId>logback-classic</artifactId>
  <version>1.2.6</version>
</dependency>

As it stands now, the whole POM file looks like this.

You'll also need to create an application.properties file which you won't see in my code repo because I really don't feel like sharing my API key with complete strangers. It should include an openai.token property.

openai.token=whatever-your-key-is

Next, let's start coding.

Supporting Classes

Let's make it easy to get the service that Mr. Kanning has provided for us with an OpenAiServiceHelper class:

public class OpenAiServiceHelper {

    public static OpenAiService getOpenAiService() {
        //make sure you create an application.properties file in src/main/resources
        //and then assign your OpenAI key to the openai.token property
        final String token = AiProperties.get("openai.token");

        final OpenAiService service = new OpenAiService(token, Duration.ofSeconds(30));

        return service;
    }
}

That class uses a custom-made AiProperties class to get the value of openai.token from application.properties. Feel free to check it out at the link.

The code above just instantiaties OpenAiService and returns it. Nothing too complicated.

If you're wondering about that 30-second duration in the constructor, it sets the timeout. You'll need that with this API or you could get some timeout issues.

Next, add another supporting class for chat completions.

public class ChatCompletionRequestHelper {

    private static final String MODEL = "gpt-3.5-turbo";

    public static ChatCompletionRequest getRequest(final List<ChatMessage> messages) {
        final ChatCompletionRequest chatCompletionRequest = ChatCompletionRequest
                .builder()
                .model(MODEL)
                .messages(messages)
                .build();

        return chatCompletionRequest;
    }
}

The recommended model as of this writing is gpt-3.5-turbo. That might have changed by the time you read this, so be sure to check out the recommended model for the current epoch.

I've hardcoded that model name because I don't expect it to change too much. 

The only method in the class takes a List of ChatMessage objects and creates a request from them.

You can think of this as creating a request body under the covers.

Running Around

Next, create an executable Java class that uses those two support classes to create a request, send it to the OpenAI API, and parse the response.

Here's what that class looks like:

public class BasicCompletionTest {
    public static void main(String[] args) {
        final OpenAiService service = OpenAiServiceHelper.getOpenAiService();

        final List<ChatMessage> messages = getMessages();
        final ChatCompletionRequest chatCompletionRequest = ChatCompletionRequestHelper.getRequest(messages);

        service.createChatCompletion(chatCompletionRequest)
                .getChoices()
                .forEach(System.out::println);
    }

    private static List<ChatMessage> getMessages() {
        final List<ChatMessage> messages = new ArrayList<>();
        final ChatMessage systemMessage = new ChatMessage(ChatMessageRole.SYSTEM.value(), "You are a helpful assistant.");
        final ChatMessage userMessage = new ChatMessage(ChatMessageRole.USER.value(), "What is the best tool for API testing?");

        messages.add(systemMessage);
        messages.add(userMessage);

        return messages;
    }
}

Let's start at the bottom.

That getMessages() method instantiates a couple of ChatMessage objects. Each object includes a role.

And guess what? You've already seen both of those roles in action. When you sent the Postman request, you used a "system" role and a "user" role.

The system role message here is the fairly generic "You are a helpful assistant." As a rule of thumb, you'll want to avoid that message. But since you're just testing things out for now feel free to roll with it.

The user role message is the question you're asking OpenAI to answer. In this case, it's: "What is the best tool for API testing?"

Now on to the main() method.

That one starts by instantiating an OpenAiService object using the supporting class from above.

Then, it grabs the two chat messages from the getMessages() method. It uses those methods to instantiate the ChatCompletionRequest object via the helper class you saw in the previous section.

Remember, as I said before: you'll use the /chat/completions endpoint most of the time. The ChatCompletionRequest object works with that endpoint.

The final line in the main() method simply uses the service to call the downstream OpenAI API with the messages you specified. Then, it reads the responses and spits them out in the console.

Okay, now just run the code using IntelliJ. Check the console output.

My output looks something like this:

1. Postman: A widely-used and comprehensive API testing tool that offers features like creating and managing requests, generating test scripts, and analyzing responses.

2. SoapUI: An open-source testing tool specifically designed for testing SOAP and REST APIs. It provides a user-friendly interface and extensive functionality for creating and executing API tests.

3. JMeter: Originally developed for load testing, Apache JMeter can also be used for API functional testing. It offers a wide range of features and supports multiple protocols including HTTP, SOAP, REST, FTP, and more.

4. Insomnia: A lightweight and intuitive REST API testing tool with features like API request building, response inspection, and test suite creation. It supports various authentication types and generates comprehensive test reports.

5. Rest-Assured: A Java-based testing library that provides a fluent and easy-to-use interface for API testing. It integrates well with popular Java development frameworks and offers features like request specification, response validation, and authentication.

Ultimately, the best tool for you depends on factors like your project requirements, programming language preferences, budget, and personal preferences. It's recommended to try out a few tools and choose the one that suits your needs best.

Again, don't be surprised if your output is different. OpenAI is known to vary its responses from time to time.

But if you got back anything that looks like that, then you're in great shape.

Wrapping It Up

Congrats! You've now taken your first step into a larger world.

Over to you. Play with the code using different prompts. 

Just be sure to keep an eye on your token usage. You don't want to hit your limit too early.

Also, feel free to check out the source code for this project. You can clone it and run it locally.

Have fun!

Photo by Pavel Danilyuk: https://www.pexels.com/photo/a-bearded-man-playing-chess-8438923/