I need to use the OpenAI API and am struggling to format the request. I started by referencing the curl code that is listed in the OpenAI API playground, and this code worked in my terminal. That request is here:
curl https://api.openai.com/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $OPENAI_API_KEY" \
-d '{
"model": "gpt-4o",
"messages": [
{
"role": "user",
"content": [
{
"type": "text",
"text": "Write a haiku about weightlifting"
}
]
}
],
"temperature": 1,
"max_tokens": 2048,
"top_p": 1,
"frequency_penalty": 0,
"presence_penalty": 0,
"response_format": {
"type": "text"
}
}'
Then, I started working on translating that request into swift instead of curl. I've been referencing some YouTube tutorials, and here is my code so far.
let openAiUrl = URL(string: "https://api.openai.com/v1/chat/completions")!
var request = URLRequest(url: openAiUrl)
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("Bearer \(openAiApiKey)", forHTTPHeaderField: "Authorization")
request.httpMethod = "POST"
let httpBody: [String: Any] = [
"messages" : [
{
"role": "user", //Error: consecutive statements on a line must be separated by ';'
"content": "Write a haiku about weightlifting"
}
],
"model": "gpt-4o",
"max_tokens" : 100,
"temperature": String(temperature),
"frequency_penalty": 0,
"presence_penalty": 0,
"response_format": { //Error: consecutive statements on a line must be separated by ';'
"type": "text"
}
]
I am getting the error that says "Consecutive statements on a line must be separated by ';'" on the two lines that are using curly braces.
What do I need to do to format the API request? The temperature variable is a Double that is currently set to 1.0.
Try this approach using a JSONEncoder
to encode the json parameters, such as:
let body = """
{
"messages" : [
{
"role": "user",
"content": "Write a haiku about weightlifting"
}
],
"model": "gpt-4o",
"max_tokens" : 100,
"temperature": 1.0,
"frequency_penalty": 0,
"presence_penalty": 0,
"response_format": {
"type": "text"
}
}
"""
do {
request.httpBody = try JSONEncoder().encode(body)
let (responseData, response) = try await URLSession.shared.data(for: request)
print("-----> \n \(String(data: responseData, encoding: .utf8) as AnyObject) \n")
} catch {
print("---> error: \(error)")
}
EDIT-1
Here is my test code using SwiftUI. Since I don't have a key I cannot fully test this code, but it compiles and gives some info about the response.
import SwiftUI
struct ContentView: View {
let openAiApiKey = "for testing"
var body: some View {
Text("testing")
.task {
await doPost()
}
}
func doPost() async {
let openAiUrl = URL(string: "https://api.openai.com/v1/chat/completions")!
var request = URLRequest(url: openAiUrl)
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("Bearer \(openAiApiKey)", forHTTPHeaderField: "Authorization")
request.httpMethod = "POST"
let body = """
{
"messages": [
{
"role": "user",
"content": "Write a haiku about weightlifting"
}
],
"model": "gpt-4o",
"max_tokens" : 100,
"temperature": 1.0,
"frequency_penalty": 0,
"presence_penalty": 0,
"response_format": {
"type": "text"
}
}
"""
do {
request.httpBody = try JSONEncoder().encode(body)
let (responseData, response) = try await URLSession.shared.data(for: request)
print("-----> responseData \n \(String(data: responseData, encoding: .utf8) as AnyObject) \n")
}
catch { print(error) }
}
}
EDIT-2
another alternative,
struct ContentView: View {
let openAiApiKey = "for testing"
var body: some View {
Text("testing")
.task {
let url = URL(string: "https://api.openai.com/v1/chat/completions")!
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.setValue("Bearer \(openAiApiKey)", forHTTPHeaderField: "Authorization")
let requestBody: [String: Any] = [
"model": "gpt-4o",
"messages": [
[
"role": "user",
"content": [
[
"type": "text",
"text": "Write a haiku about weightlifting"
]
]
]
],
"temperature": 1,
"max_tokens": 2048,
"top_p": 1,
"frequency_penalty": 0,
"presence_penalty": 0,
"response_format": [
"type": "text"
]
]
do {
request.httpBody = try JSONSerialization.data(withJSONObject: requestBody)
let (responseData, response) = try await URLSession.shared.data(for: request)
print("-----> responseData \n \(String(data: responseData, encoding: .utf8) as AnyObject) \n")
}
catch { print(error) }
}
}
}