Преобразование запроса curl и отправка файла как часть полезной нагрузки в Golang - PullRequest
0 голосов
/ 30 апреля 2020

У меня есть запрос curl, который выглядит следующим образом

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

http python для этого запроса curl выглядит следующим образом

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

Я хотел бы преобразовать его в эквивалент Golang http запрос. Я пробовал несколько Golang библиотек, таких как grequests, http, а также запись в блоге здесь https://matt.aimonetti.net/posts/2013-07-golang-multipart-file-upload-example/ Но, похоже, ни одна из них не работает. Это пример grequest, который я попытался

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")
    }

}

Это дает мне следующую ошибку

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

Я также попытался преобразовать запрос curl в golang с помощью почтальона, но он также не работает так как запрос состоит в загрузке файла.

Обратите внимание, что в коде python я просто не посылаю файл, а словарь файла. Я попытался преобразовать запрос curl с помощью почтальона в Golang, но он не работал, так как мы также должны отправить файл как часть полезной нагрузки.

Спасибо за вашу помощь.

1 Ответ

0 голосов

Если файл находится в том же каталоге, что и файл go, попробуйте этот фрагмент кода. Я обнаружил

no such host error, но я думаю, что это будет работать.

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)
    }
}
...