0

I am trying to access the IBM Watson Translation service using Swift without the SDK). I am able to access it from the command line using curl using the following:

curl -X POST --user "apikey:MYLONGAPIKEY" --header "Content-Type: application/json" --data '{"text": ["Hello, world.", "How are you?"], "model_id":"en-es"}' "https://api.us-east.language-translator.watson.cloud.ibm.com/instances/9b5fbfbf-3715-4690-822d-abfbb68e96ff/v3/translate?version=2018-05-01"

I am trying to translate the above curl request into an URLrequest in Swift but getting an authentication error:

Here is my current Swift code that gives the 401 authentication error.

     let url = URL(string: https://api.us-east.language-translator.watson.cloud.ibm.com/instances/9b5fbfbf-3715-4690-822d-abfbb68e96ff/v3/translate?version=2018-05-01)
        let authstring = "apikey:" +  myLongKey
      var request = URLRequest(url: url!)
        request.addValue("application/json", forHTTPHeaderField: "Accept")//sets mime type
        request.addValue(authstring, forHTTPHeaderField: "Authorization")
        request.httpMethod = "POST"
        
        let task = URLSession.shared.dataTask(with: request) { data, response, error in
            guard error == nil else {
                print("error reaching watson is: ",error!)
                return
            }
            guard let data = data else {
                print("Data is empty")
                return
            }
//convert to json and so something
           
        }

        task.resume()
    }

Edit:

The issue may have something to do with prepending Basic to the authorization string. According to reqbin, the above curl translates to the following (working) http request so I guess my question is equivalent to translating the following into a SWIFT request:

POST /instances/9b5fbfbf-3715-4690-822d-abfbb68e96ff/v3/translate?version=2018-05-01 HTTP/1.1
Authorization: Basic LONG_KEY_DIFFERENT_FROM_MY_LONG_KEY
Host: api.us-east.language-translator.watson.cloud.ibm.com
Content-Type: application/json
Content-Length: 63

{"text": ["Hello, world.", "How are you?"], "model_id":"en-es"} 

Here it is in Python from reqbin (reqbin doesn't do Swift):

import requests
from requests.structures import CaseInsensitiveDict

url = "https://api.us-east.language-translator.watson.cloud.ibm.com/instances/9b5fbfbf-3715-4690-822d-abfbb68e96ff/v3/translate?version=2018-05-01"

headers = CaseInsensitiveDict()
headers["Content-Type"] = "application/json"
headers["Authorization"] = "Basic LONG_KEY_DIFFERENT_FROM_MY_LONG_KEY"

data = '{"text": ["Hello, world.", "How are you?"], "model_id":"en-es"}'


resp = requests.post(url, headers=headers, data=data)

print(resp.status_code)

What am I doing wrong?

Thanks in advance for any suggestions.

user6631314
  • 1,751
  • 1
  • 13
  • 44
  • Maybe `request.addValue("Bearer \(request.addValue("Bearer \(secretKey)", forHTTPHeaderField: "Authorization"))", forHTTPHeaderField: "Authorization")`? Note that you also didn't put the `request.addValue("application/json", forHTTPHeaderField: "Content-Type")` as stated in the doc, nor the JSON body. – Larme Apr 04 '21 at 16:03
  • Also, curl sets a `Content-Type` of `application/json`, not `Accept`. And you never set the `httpBody` of your request. – Rob Apr 04 '21 at 16:11
  • swapped content-type but still 401 error. Can you explain the Bearer line? just putting it in as you state substituting myLongKey for secretKey still gives 401 error – user6631314 Apr 04 '21 at 18:44
  • For anyone with this issue, found the answer here. You have to convert to the right encoding format and specify Basic: https://stackoverflow.com/questions/24379601/how-to-make-an-http-request-basic-auth-in-swift – user6631314 Apr 04 '21 at 21:04

0 Answers0