Jackie Fahmy
Jackie Fahmy

Reputation: 1

Request-streaming gRPC client request error

When I run my gRPC client and it attempts to stream a request to the server I get this error: "TypeError: has type list_iterator, but expected one of: bytes, unicode"

Do I need to encode the text I'm sending in some way? Error message makes some sense, as I am definitely passing in an iterator. I assumed from the gRPC documentation that this is what was needed. (https://grpc.io/docs/tutorials/basic/python.html#request-streaming-rpc)Anyway, sending a list or string yields a similar error. At the moment I am sending a small test list of strings to the server in the request, but I plan to stream requests with very large amounts of text in the future.

Here's some of my client code.

def gen_tweet_space(text):
    for tweet in text:
        yield tweet

def run():
 channel = grpc.insecure_channel('localhost:50050')
 stub = ProseAndBabel_pb2_grpc.ProseAndBabelStub(channel)

 while True:
     iterator = iter(block_of_text)
     response = stub.UserMarkov(ProseAndBabel_pb2.UserTweets(tweets=iterator))

Here's relevant server code:

def UserMarkov(self, request_iterator, context):
        return ProseAndBabel_pb2.Babel(prose=markov.get_sentence(request_iterator.tweets))

Here's the proto where the rpc and messages are defined:

service ProseAndBabel {

rpc GetHaiku (BabelRequest) returns (Babel) {}
rpc GetBabel (BabelRequest) returns (Babel) {}
rpc UserMarkov (stream UserTweets) returns (UserBabel) {}
}

message BabelRequest{
  string ask = 1;
}

message Babel{
  string prose = 1;
}

message UserTweets{
  string tweets = 1;
}

message UserBabel{
  string prose = 1;
}

I've been successful getting the non-streaming rpc to work, but having trouble finding walkthroughs for request side streaming for python applications so I'm sure I'm missing something here. Any guidance/direction appreciated!

Upvotes: 0

Views: 2634

Answers (1)

Eric G
Eric G

Reputation: 4058

You need to pass the iterator of requests to the gRPC client stub, not to the protobuf constructor. The current code tries to instantiate a UserTweets protobuf with an iterator rather than an individual string, resulting in the type error.

response = stub.UserMarkov(ProseAndBabel_pb2.UserTweets(tweets=iterator))

You'll instead need to have your iterator to return instances of ProseAndBabel_pb2.UserTweets, each of which wraps one of the request strings you would like to send, and pass the iterator itself to the stub. Something like:

iterator = iter([ProseAndBabel_pb2.UserTweets(tweets=x) for x in block_of_text])
response = stub.UserMarkov(iterator)

Upvotes: 1

Related Questions