Golang 中通过gRPC调用Python实现的功能
背景
有时候,我们在python中实现了一个功能,这功能如果用golang重新写呢,会比较麻烦,如果要在golang中调用python中的功能。 方式有很多,主要就是两个程序如果沟通的问题,那方式就各种各样了,可以通过http协议,json/xml等格式,或者tcp, 当然还有个 选择就是gRPC
python 实现 rpc server
这个网上资料比较多,通过protobuf生成代码,实现server端的功能。
golang 实现 rpc client
同样的,根据proto文件,生成go code, 可以通过client连接rpc server
目前的一个小实现
- 主要功能用python实现,同时python实现了 rpc server功能,在gin里面,通过client来调用
package main
import (
"context"
"fmt"
"io/ioutil"
"log"
"net/http"
"os"
"path/filepath"
pb "github.ibm.com/assetharvest/text-detection-tf/proto"
"github.com/gin-gonic/gin"
"google.golang.org/grpc"
)
const (
address = "localhost:50501"
)
func main() {
r := gin.Default()
r.GET("/ping", func(c *gin.Context) {
c.JSON(200, gin.H{
"message": "pong",
})
})
r.POST("/", func(c *gin.Context) {
// single file
file, err := c.FormFile("file")
if err != nil {
c.String(http.StatusBadRequest, fmt.Sprintf("get form err: %s", err.Error()))
return
}
filename := filepath.Base(file.Filename)
// create temp directory
dname, err := ioutil.TempDir("", "textdetector")
if err != nil {
c.String(http.StatusBadRequest, fmt.Sprintf("get form err: %s", err.Error()))
return
}
defer os.RemoveAll(dname)
fname := filepath.Join(dname, filename)
// Upload the file to specific dst.
c.SaveUploadedFile(file, fname)
conn, err := grpc.Dial(address, grpc.WithInsecure())
if err != nil {
log.Fatalf("did not connect: %v", err)
}
defer conn.Close()
client := pb.NewTextDetecterClient(conn)
// Contact the server and print out its response.
r, err := client.TextDetect(context.Background(), &pb.TextDetectRequest{Filename: fname})
if err != nil {
log.Fatalf("could not connect: %v", err)
}
log.Printf("%+v\n", r.Result)
// c.JSON(200, r.Result)
c.Writer.Header().Set("Content-Type", "application/json")
c.Writer.WriteHeader(200)
c.Writer.WriteString(r.Result)
})
r.Run(":3000")
}