pythongopython-requestsgorilla

How to send OpenCV Image using python requests to Go Endpoint


Here is the code for my camera script

import cv2
import requests
from datetime import datetime
from time import sleep

def sendImage(frame):
    imencoded = cv2.imencode(".jpg", frame)[1]
    now = datetime.now()
    seq = now.strftime("%Y%m%d%H%M%S")
    file = {'file': (seq+'.jpg', imencoded.tobytes(), 'image/jpeg')}
    response = requests.post("http://localhost:3004/", files=file, timeout=5)
    return response

def takeImage():
    cap = cv2.VideoCapture(0)
    ret, frame = cap.read()
    print(sendImage(frame))
    cap.release()


while 1:
    takeImage()
    sleep(5)

and my Go Server

package main

import (
    "fmt"
    "log"
    "net/http"

    "github.com/gorilla/mux"
)

func imgHandler(w http.ResponseWriter, r *http.Request) {
    fmt.Println("recieved request!")

    r.ParseMultipartForm(10 << 20)

    file, handler, err := r.FormFile("myFile")

    if err != nil {
        fmt.Println("error!")
        return
    }

    defer file.Close()
    fmt.Println(handler.Filename)
}

func getHandler(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "Hello World API!")
}

func main() {
    r := mux.NewRouter()

    r.HandleFunc("/", imgHandler).Methods("POST")
    r.HandleFunc("/", getHandler).Methods("GET")

    http.Handle("/", r)

    log.Fatal(http.ListenAndServe(":3004", nil))
}

I have no idea why I keep on getting an error on my FormFile function. My end goal is to have a secure connection to an endpoint so that I can send images from my raspberry pi to my server and have it saved locally. How can I do this so I send files to my Go endpoint using the python requests library. I've already seen solutions that involve using elements on a html page that works.


Solution

  • In Python you call the field file where in Go you try to access myFile. The change to the Go code was:

    file, handler, err := r.FormFile("file")
    

    To find this out, I've changed the debug line to print the error as well:

    if err != nil {
        fmt.Printf("error: %s\n", err)
        return
    }
    

    (In general, use log.Printf in servers :)