0
votes

I have a curl request that looks like this

curl -X POST https://kon-stage-ew1.pet.io/predict/pet-find/v1/predict \
  -H 'x-kon-Predict-Backend: https://kon-94fkr5wXRCeNu3IiDXzXFg-stage.cloud.pet.io' \
  -H 'x-analyzer-id: Feature:pet-find:Service-33f50d68d3db4fec9c75b73d3b83e016' \
  -H 'x-api-key: redStagekey' \
  -F 'properties={}' \
  -F content=@/Users/peter/Documents/01.jpg

The python http for this curl request looks like this

image1 = '01.jpg'
    headers = {
        'x-kon-Predict-Backend': 'https://kon-94fkr5wXRCeNu3IiDXzXFg-stage.cloud.pet.io',
        'x-analyzer-id': 'Feature:pet-find:Service-33f50d68d3db4fec9c75b73d3b83e016',
        'x-api-key': 'redStagekey',
    }

    payload = {'properties':'{}'}

    files = {
        'content':open(image1, 'rb')
    }

    response = requests.post('https://kon-stage-ew1.pet.io/predict/pet-find/v1/predict', headers=headers, data = payload, files=files)
    return response.content

I would like to convert this to equivalent Golang http request. I tried several Golang libraries like grequests, http and also the blog post here https://matt.aimonetti.net/posts/2013-07-golang-multipart-file-upload-example/ But none of them seem to work. This is sample grequest that I tried

package main

import (
    "github.com/levigross/grequests"
    "fmt"
)

func main(){

    url := "https://kon-stage-ew1.pet.io/predict/exposure-defect/v1/predict"

    headers := map[string]string{
        "x-kon-Predict-Backend": "https://kon-94fkr5wXRCeNu3IiDXzXFg-stage-eu-west-1.stage.cloud.pet.io",
        "x-analyzer-id": "Feature:pet-find:Service-33f50d68d3db4fec9c75b73d3b83e016",
        "x-api-key": "redStageKey",
    }

    payload := map[string]string{
        "properties":"{}",
    }

    file_upload, err := grequests.FileUploadFromDisk("/Users/akhikuma/Documents/01.jpg")

    if err != nil {
        fmt.Println("Unable to open file: ", err)
    }

    ro := &grequests.RequestOptions{
        Headers: headers,
        Files: file_upload,
        Data: payload,
    }
    resp, err := grequests.Post(url,ro)

    if err!=nil {
        fmt.Println("Something wrong happened in post request: ", err)
        fmt.Println(err)
    }

    fmt.Println(resp)
    if resp.Ok != true {
        fmt.Println("Request did not return OK")
    }

}

This gives me following error

{"status_code": 400, "reason": "('Content data is missing. Check multipart file upload.', 400)"}
Request did not return OK

I also tried converting the curl request to golang using the postman but it is also not working since the request consists of uploading the file.

Note that in the python code I just don't send file but a dictionary of the file. I tried converting the curl request using the postman to Golang but it not working since we also have to send the file as part of the payload.

Thanks for your help.

1
You should show your Go code and what didn't work. It seems this should not be too hard. Generating a multipart message is some work but reading a file and creating a POST request are pretty basic task as you see in the article you linked. Also: "it is not working" is not an actionable problem description: Please be much more specific.Volker
Have you tried to use the Import function in Postman? It will have sample code for GolangSteve Lam
@SteveLam I tried postman import function but this is not working. It gives 500 Internal error even though curl request work perfectly fine.akhilesh kumar
@Volker I have added the sample go lang code and the response that I am getting from the server.akhilesh kumar
The issue is I dont know how to create a dictionary with content as key and file reader handle as value and pass that to http request in Go. As you can see from the python code, I am able to create files which is a dictionary with contents as key and open(image1, 'rb') as value. Not sure how to do that in golang.akhilesh kumar

1 Answers

0
votes

With the file in same directory of go file, try this piece of code.I encountered

no such host error but I think this will work.

package main

import (
    "bytes"
    "fmt"
    "io"
    "log"
    "mime/multipart"
    "net/http"
    "os"
    "path/filepath"
)

func main() {
    path, _ := os.Getwd()
    path += "/your/filename/here"

    url := "https://kon-stage-ew1.pet.io/predict/exposure-defect/v1/predict"

    file, err := os.Open(path)
    if err != nil {
        log.Fatal(err)
    }
    defer file.Close()

    body := &bytes.Buffer{}
    writer := multipart.NewWriter(body)
    part, err := writer.CreateFormFile("content", filepath.Base(path))
    if err != nil {
        log.Fatal(err)
    }
    _, err = io.Copy(part, file)

    err = writer.WriteField("properties", "{}")
    if err != nil {
        log.Fatal(err)
    }
    err = writer.Close()
    if err != nil {
        log.Fatal(err)
    }

    client := http.Client{}
    req, err := http.NewRequest("POST", url, body)
    if err != nil {
        log.Fatal(err)
    }
    req.Header.Set("Content-Type", writer.FormDataContentType())
    req.Header.Set("x-kon-Predict-Backend", "https://kon-94fkr5wXRCeNu3IiDXzXFg-stage-eu-west-1.stage.cloud.pet.io")
    req.Header.Set("x-analyzer-id", "Feature:pet-find:Service-33f50d68d3db4fec9c75b73d3b83e016")
    req.Header.Set("x-api-key", "redStageKey")

    resp, err := client.Do(req)
    if err != nil {
        log.Fatal(err)
    } else {
        body := &bytes.Buffer{}
        _, err := body.ReadFrom(resp.Body)
        if err != nil {
            log.Fatal(err)
        }
        resp.Body.Close()
        fmt.Println(resp.StatusCode)
        fmt.Println(resp.Header)
        fmt.Println(body)
    }
}