2

Lets say below is the proto for bi-directional stream

service RouteGuide {
  // A Bidirectional streaming RPC.
  //
  // Accepts a stream of RouteNotes sent while a route is being traversed,
  // while receiving other RouteNotes (e.g. from other users).
  rpc RouteChat(stream RouteNote) returns (stream RouteNote) {}
}

Go defines an interface to send & rec messages inside a bidirectional stream from server to client & vice-versa : go interface. But I couldn't find the same in Python, to send the response inside the stream without making an additional RouteChat call.

Also the example provided doesnt talk about sending a request back from client

How can we send the request back to server from client from python grpc clients with in the same stream?


def generate_messages():
    messages = [
        make_route_note("First message", 0, 0),
        make_route_note("Second message", 0, 1),
        make_route_note("Third message", 1, 0),
        make_route_note("Fourth message", 0, 0),
        make_route_note("Fifth message", 1, 0),
    ]
    for msg in messages:
        print("Sending %s at %s" % (msg.message, msg.location))
        yield msg


def guide_route_chat(stub):
    responses = stub.RouteChat(generate_messages())
    for response in responses:
        print("Received message %s at %s" % (response.message, response.location))
    
chinmay
  • 672
  • 6
  • 15

2 Answers2

1

For the sync stack (i.e. not asyncio), there is no API like this. Instead, you're expected to pass in an iterator of your outgoing requests. See this previous SO answer for an example of that.

The asyncio API however does have a write/read API that is very similar to Go's.

Richard Belleville
  • 1,445
  • 5
  • 7
  • Yes, I figured it out by customizing the generator. It worked for me. Not tried asyncio yet. Thanks! – chinmay May 11 '23 at 16:30
-1

You can use the same stream object to send and receive messages in a bidirectional gRPC. To send a message back to the server from the client, you can simply call the stream.write() method on the stream object with the message you want to send.

You can change this function of yours to be this way:

def guide_route_chat(stub):
    stream = stub.RouteChat(generate_messages())
    for response in stream:
        print("Received message %s at %s" % (response.message, response.location))
        # Send a message back to the server
        request = RouteNote()
        request.message = "Sending message back to server."
        request.location.latitude = 37.7749
        request.location.longitude = -122.4194
        stream.write(request)

It is important to keep in mind that the stream needs to be in active state for you to be able to send messages back. You can check this via stream.isactive()

  • I didn't find `write()` method. Got the error `Failed to connect gRPC, error: '_MultiThreadedRendezvous' object has no attribute 'write'` – chinmay Apr 28 '23 at 10:03