-2

I currently have made a REST API using Alamofire in swiftUI. The request is a post method to this URL: https://api.openai.com/v1/engines/text-davinci-002/completions, which is basically sending a question to the OpenAI API and supposed to get the answer in JSON format. I have made an API key in OpenAI and have included it in my code.

The problem I am facing is that when getting the input, I recieve the following error:

Error: Response status code was unacceptable: 400.

I first tried to make sure if my API key was correct and it was. I also tried to see if a cURL statement would work to check if it was an error with the URL.
I used this cURL statement:

curl -X POST \
  https://api.openai.com/v1/engines/text-davinci-002/completions \
  -H 'Authorization: Bearer my-api-key' \
  -H 'Content-Type: application/json' \
  -d '{
        "prompt": "What is quantum mechanics?",
        "temperature": 0.7,
        "max_tokens": 20,
        "top_p": 1,
        "frequency_penalty": 0,
        "presence_penalty": 0
}'

Which worked fine and gave me a correct output:

{"id":"cmpl-6hhWBlzZHrLtV4RKCtjL63CLoTvPi","object":"text_completion","created":1675873407,"model":"text-davinci-002","choices":[{"text":"\n\nQuantum mechanics is a branch of physics that studies the behavior of matter and energy in the","index":0,"logprobs":null,"finish_reason":"length"}],"usage":{"prompt_tokens":5,"completion_tokens":20,"total_tokens":25}}

If it helps, here's my code:

//
//  chat.swift
//  titan
//
//  Created by Refluent on 08/02/2023.
//

import SwiftUI
import Alamofire

struct Message: Hashable {
    let sender: String
    let content: String
}

struct OpenAIResponse: Decodable {
    let completions: [Completion]
    
    struct Completion: Decodable {
        let text: String
    }
}

struct chatView: View {
    @State private var response: String = ""
    @State private var messages: [Message] = []
    @State private var userInput: String = ""
    
    let apiKey = "my-api-key"
    let model = "text-davinci-002"
    
    var body: some View {
        VStack {
            Text("Response from OpenAI API:")
            List(messages, id: \.self) { message in
                Text("\(message.sender): \(message.content)")
            }
            
            TextField("Enter your question", text: $userInput)
                .padding()
            
            Button(action: {
                self.sendRequest()
            }) {
                Text("Send")
            }
        }
    }
    
    func sendRequest() {
        let headers: HTTPHeaders = ["Authorization": "Bearer \(apiKey)", "Content-Type": "application/json"]
        
        let parameters: Parameters = ["prompt": userInput, "model": model]
        
        messages.append(Message(sender: "Me", content: userInput))
        userInput = ""
        
        AF.request("https://api.openai.com/v1/engines/text-davinci-002/completions", method: .post, parameters: parameters, headers: headers)
            .validate()
            .responseDecodable(of: OpenAIResponse.self) { response in
                switch response.result {
                case .success(let value):
                    let text = value.completions[0].text
                    self.messages.append(Message(sender: "ChatGPT", content: text))
                case .failure(let error):
                    self.messages.append(Message(sender: "ChatGPT", content: "Error: \(error.localizedDescription)"))
                }
            }
    }
}

For more context about my code, here it is:

I'm sending a post request to this URL, then getting the output and saving it in an array alongside the original input. The input and the output is then displayed as a chat.

Does anyone know why I am recieving this error? Did I miss a crucial part in my code?

Thanks in advance btw.

After reading through the comments, I realised that this isn't exactly something to do in Swift, so I will be implementing this in the server side. I apoligize for wasting your time.

Refluent
  • 93
  • 8
  • 2
    You shouldn’t be doing this in swift, your API key should not be included in a client side app, somewhere in open ai’s documentation they emphasize this. Calls should be made server side. – lorem ipsum Feb 08 '23 at 17:00
  • Is there a library that can help me do that? I'm new to swiftUI and didn't know that you could build a backend. I'll look into that. Thanks – Refluent Feb 09 '23 at 02:45
  • Try firebase functions, this wont be done in Swift or SwiftUI, it isn't in Xcode either, Xcode, Swift and SwiftUI are front end. – lorem ipsum Feb 09 '23 at 02:52
  • You are sending `["prompt": userInput, "model": model]`, which is a totallly different content than the one in cURL (in terms of json structure/hierarchy/modelisation). So if it's not the expected JSON, it seems normal to have an error. You can use .validate().curlDescription { print("AF cURL equivalent: \($0)") }.responseDecodable(of:...)` to see what your request and see the differences. – Larme Feb 09 '23 at 09:59
  • https://github.com/vedlai/OpenAISwiftDI – lorem ipsum May 02 '23 at 19:24

1 Answers1

0

You're sending a model as a parameter to an engine url (which is model-specific). Try posting to https://api.openai.com/v1/completions. The engine-specific endpoints are deprecated anyways so it's best to update your call now.

I'm Joe Too
  • 5,468
  • 1
  • 17
  • 29