3

my goal is to implement a gRPC client that is unfamiliar of the proto file (only knows server/service port number) - the client find the service on run-time (reflection)

my client should be able to:

  • connect to the server
  • learn which server capabilities exists (including messages)
  • send rpc requests to the enable-reflection server

i already see an example in Go & Java and failed to find one in python that work for me. i successfully used "evans" cli client with my server but i want to implement cli client on my own.

https://github.com/grpc/grpc/blob/master/doc/server_reflection_tutorial.md

i look on this example of how to implementing the server & i can use some help to better understand how to implement the client.

https://github.com/grpc/grpc/blob/master/examples/python/helloworld/greeter_server_with_reflection.py

my questions are:

  1. how to find the current service from the client only from port number?
  2. how to communicate with the server without importing the generated proto files?

server side:

from __future__ import print_function
import logging

import grpc

import helloworld_pb2
import helloworld_pb2_grpc


def run():
    # NOTE(gRPC Python Team): .close() is possible on a channel and should be
    # used in circumstances in which the with statement does not fit the needs
    # of the code.
    #
    # For more channel options, please see https://grpc.io/grpc/core/group__grpc__arg__keys.html
    with grpc.insecure_channel(target='localhost:50051',
                               options=[('grpc.lb_policy_name', 'pick_first'),
                                        ('grpc.enable_retries', 0),
                                        ('grpc.keepalive_timeout_ms', 10000)
                                       ]) as channel:
        stub = helloworld_pb2_grpc.GreeterStub(channel)
        # Timeout in seconds.
        # Please refer gRPC Python documents for more detail. https://grpc.io/grpc/python/grpc.html
        response = stub.SayHello(helloworld_pb2.HelloRequest(name='you'),
                                 timeout=10)
    print("Greeter client received: " + response.message)


if __name__ == '__main__':
    logging.basicConfig()
    run()

client side:

from __future__ import print_function
import logging

import grpc

import helloworld_pb2
import helloworld_pb2_grpc


def run():
    # NOTE(gRPC Python Team): .close() is possible on a channel and should be
    # used in circumstances in which the with statement does not fit the needs
    # of the code.
    with grpc.insecure_channel('localhost:50051') as channel:
        stub = helloworld_pb2_grpc.GreeterStub(channel)
        response = stub.SayHello(helloworld_pb2.HelloRequest(name='you'))
    print("Greeter client received: " + response.message)


if __name__ == '__main__':
    logging.basicConfig()
    run()
  • Did you find an answer to this dilemma? I tried using the `grp-request` python library that can do reflection, but unfortunately it returns Dict after a request, and it looses all the fields on the messages that are left default. These fields are not sent, by the gRPC protocol, so this may be a half solution to your problem. https://pypi.org/project/grpc-requests/ – Patkos Csaba Mar 26 '21 at 17:41

0 Answers0