Using the JUCE URL Reference to connect to the open AI GPT API

Hi! I’m Just posting to see if anyone has had any experience with the Juce URL Reference class and the GPT API. I am currently trying to implement this function that sends user input to the API and for some reason I cannot get it to recognize my API key. Here is the relevant function:

void NewProjectAudioProcessor::sendUserInputToGPT(const juce::String& userInput)

{

juce::URL url(“https://api.openai.com/v1/engines/gpt-3.5-turbo/completions”);

juce::StringPairArray headers;

headers.set(“Content-Type”, “application/json”);

juce::String apiKey = “MY API KEY”;

headers.set(“Authorization”, "Bearer " + apiKey);

DBG("API Key: " << apiKey);

DBG("Constructed URL: " << url.toString(true));

// Construct the request body with the conversation format

juce::String requestBody = R"({

“model”: “gpt-3.5-turbo”,

“messages”: [

{“role”: “system”, “content”: “You are a helpful assistant.”},

{“role”: “user”, “content”: “)” + userInput + R"("}

]

})";

DBG("Request Body: " << requestBody);

// Create InputStreamOptions and set other options

juce::URL::InputStreamOptions options(juce::URL::ParameterHandling::inPostData);

DBG("Constructed URL: " << url.toString(true));

DBG("Constructed Headers: " << headers.getDescription());

DBG("Request Body: " << requestBody);

// Make the HTTP request

auto response = url.createInputStream(options);

if (auto* stream = dynamic_castjuce::WebInputStream*(response.get()))

{

stream->withExtraHeaders(headers.getDescription() + “\r\n”).withConnectionTimeout(5000).connect(nullptr); // This may be optional but I’m not sure yet

stream->setPosition(0); // Reset position to the start

// Send POST data in chunks

int totalBytes = requestBody.getNumBytesAsUTF8();

int bytesSent = 0;

int chunkSize = 4096;

while (bytesSent < totalBytes)

{

int bytesToSend = std::min(chunkSize, totalBytes - bytesSent);

stream->read(const_cast<char*>(requestBody.toRawUTF8()) + bytesSent, bytesToSend);

bytesSent += bytesToSend;

}

}

juce::String jsonResponse = response->readEntireStreamAsString();

DBG("GPT API Response: " << jsonResponse);

}

Here is the debugging output that results:
JUCE v7.0.9

API Key: API_KEY (The actual key shows up just not sharing it here)

Constructed URL: https://api.openai.com/v1/engines/gpt-3.5-turbo/completions

Request Body: {

“model”: “gpt-3.5-turbo”,

“messages”: [

{“role”: “system”, “content”: “You are a helpful assistant.”},

{“role”: “user”, “content”: "Hello GPT Please work "}

]

}

Constructed URL: https://api.openai.com/v1/engines/gpt-3.5-turbo/completions

Constructed Headers: Content-Type = application/json, Authorization = Bearer MY_API_KEY,

Request Body: {

“model”: “gpt-3.5-turbo”,

“messages”: [

{“role”: “system”, “content”: “You are a helpful assistant.”},

{“role”: “user”, “content”: "Hello GPT Please work "}

]

}

2023-11-30 13:26:52.154158-0500 capstone_nov27[23742:665729] [connection] nw_proxy_resolver_create_parsed_array [C1 proxy pac] Evaluation error: NSURLErrorDomain: -1003

2023-11-30 13:26:52.255027-0500 capstone_nov27[23742:665736] [connection] nw_endpoint_handler_set_adaptive_read_handler [C1.1.1 104.18.7.192:443 ready socket-flow (satisfied (Path is satisfied), viable, interface: en0, ipv4, dns)] unregister notification for read_timeout failed

2023-11-30 13:26:52.255066-0500 capstone_nov27[23742:665736] [connection] nw_endpoint_handler_set_adaptive_write_handler [C1.1.1 104.18.7.192:443 ready socket-flow (satisfied (Path is satisfied), viable, interface: en0, ipv4, dns)] unregister notification for write_timeout failed

GPT API Response: OUR_KEY), or as the password field (with blank username) if you’re accessing the API from your browser and are prompted for a username and password. You can obtain an API key from https://platform.openai.com/account/api-keys.",

“type”: “invalid_request_error”,

“param”: null,

“code”: null

}

}

Any suggestions are greatly appreciated! :slight_smile: