'How to send base64 image to gRPC tf serving server instead of http request?

I have a working code when I am serving an object detection model in tf-serving and accessing it via http request. The code for the same is:

import requests
import base64
import json

URL = "http://10.10.1.38:8501/v1/models/test_model:predict" 
headers = {"content-type": "application/json"}
image = "test111.jpg"
image_content = base64.b64encode(open(image,'rb').read())
encodedStr = str(image_content, "utf-8")
body = {"signature_name": "predict_images","inputs": [{"b64":encodedStr}]}
response = requests.post(URL, data=json.dumps(body), headers = headers) 

I want to do the same but using gRPC client code.

The code for that is:

import grpc
from tensorflow_serving.apis import predict_pb2
from tensorflow_serving.apis import prediction_service_pb2_grpc

image = "test111.jpg"
image_content = base64.b64encode(open(image,'rb').read())
encodedStr = str(image_content, "utf-8")

server = 'localhost:8500'
channel = grpc.insecure_channel(server)
stub = prediction_service_pb2_grpc.PredictionServiceStub(channel)
request = predict_pb2.PredictRequest()
request.model_spec.name = 'test_model'
request.model_spec.signature_name = 'predict_images'
request.inputs['inputs'].CopyFrom(tf.contrib.util.make_tensor_proto(encodedStr, shape=[1]))
result_future = stub.Predict(request,40.)

But this is throwing the bellow error:

_Rendezvous: <_Rendezvous of RPC that terminated with:
status = StatusCode.INVALID_ARGUMENT
details = "assertion failed: [Unable to decode bytes as JPEG, PNG, GIF, or BMP]
[[{{node map/while/decode_image/cond_jpeg/cond_png/cond_gif/Assert_1/Assert}}]]"
debug_error_string = "{"created":"@1579785768.913000000","description":"Error received from peer","file":"src/core/lib/surface/call.cc","file_line":1017,"grpc_message":"assertion failed: [Unable to decode bytes as JPEG, PNG, GIF, or BMP]\n\t [[{{node map/while/decode_image/cond_jpeg/cond_png/cond_gif/Assert_1/Assert}}]]","grpc_status":3}"
>


Solution 1:[1]

If anyone is still looking for the answer, you just need to pass image bytes object as a list to tf.make_tensor_proto with dtype=tf.string.

Following code should work:

import grpc
from tensorflow_serving.apis import predict_pb2
from tensorflow_serving.apis import prediction_service_pb2_grpc

image = "test_img.jpg"
image_bytes = open(image,'rb').read()

server = 'localhost:8500'
channel = grpc.insecure_channel(server)
stub = prediction_service_pb2_grpc.PredictionServiceStub(channel)
request = predict_pb2.PredictRequest()
request.model_spec.name = 'default'
request.model_spec.signature_name = 'serving_default'
request.inputs['bytes_inputs'].CopyFrom(tf.make_tensor_proto([image_bytes], dtype=tf.string))
result_future = stub.Predict(request)

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Aleksey Vlasenko