This one
https://grpc.github.io/grpc/python/_modules/grpc.html#metadata_call_credentials
talks about metadata call credentials which seems to be similar to what the
Java client is doing. Examples of authMetadataPlugin are available at
https://www.programcreek.com/python/example/113599/grpc.AuthMetadataPlugin

Although I doubt the error "Method not found: GetVersion/GetVersion" is
because of missing CallCredentials.



On Sun, Feb 28, 2021 at 9:35 AM James Telzrow <jtelz.fa...@gmail.com> wrote:

> Hello,
>
> I am continuously getting the following error when making a gRPC call:
>
> grpc._channel._InactiveRpcError: <_InactiveRpcError of RPC that terminated
> with:
> status = StatusCode.UNIMPLEMENTED
> details = "Method not found: GetVersion/GetVersion"
> debug_error_string =
> "{"created":"@1614530914.104036000","description":"Error received from peer
> ipv4:192.168.0.69:9998","file":"src/core/lib/surface/call.cc","file_line":1068,"grpc_message":"Method
> not found: GetVersion/GetVersion","grpc_status":12}"
>
> I am making the call using this bit of Python code:
>
> def runFunc():
>      channel = grpc.insecure_channel('192.168.0.69:9998')
>      stub = grpcBisq_pb2_grpc.GetVersionStub(channel)
>      response = stub.GetVersion(grpcBisq_pb2.GetVersionRequest())
>      print(response.version)
>
> However, I know that the server has a GetVersion gRPC service with a
> GetVersion endpoint that takes a GetVersionRequest, since both the client
> and server have the following in their .proto file:
>
> service GetVersion {
>     rpc GetVersion (GetVersionRequest) returns (GetVersionReply) {
> }
> }
> message GetVersionRequest {
> }
> message GetVersionReply {
>      string version = 1;
> }
>
> The server is written in Java (and wasn't written by me) and I wrote my
> client in Python. However, the server has an example client (also written
> in Java) that uses some sort of authentication scheme, and as of now my
> Python client isn't using any type of authentication. I'm guessing this is
> what is causing the server to return the above error. In that Java client,
> the stub is created as follows:
>
> public final class GrpcStubs {
>      public final GetVersionGrpc.GetVersionBlockingStub versionService;
>      public GrpcStubs(String apiHost, int apiPort, String apiPassword) {
>           CallCredentials credentials = new
> PasswordCallCredentials(apiPassword);
>           var channel = ManagedChannelBuilder.forAddress(apiHost,
> apiPort).usePlaintext().build();
>           Runtime.getRuntime().addShutdownHook(new Thread(() -> {
>                try {
>                     channel.shutdown().awaitTermination(1, SECONDS);
>                } catch (InterruptedException ex) {
>                     throw new IllegalStateException(ex);
>                }
>           }));
>           this.versionService
> = GetVersionGrpc.newBlockingStub(channel).withCallCredentials(credentials);
>      }
> }
>
> PasswordCallCredentials is defined in PasswordCallCredentials.java as
> follows:
>
> /**
> * Sets the {@value PASSWORD_KEY} rpc call header to a given value.
> */
> class PasswordCallCredentials extends CallCredentials {
>      public static final String PASSWORD_KEY = "password";
>      private final String passwordValue;
>      public PasswordCallCredentials(String passwordValue) {
>           if (passwordValue == null)
>                throw new IllegalArgumentException(format("'%s' value must
> not be null", PASSWORD_KEY));
>           this.passwordValue = passwordValue;
>      }
>      @Override
>      public void applyRequestMetadata(RequestInfo requestInfo, Executor
> appExecutor, MetadataApplier metadataApplier) {
>           appExecutor.execute(() -> {
>                try {
>                     var headers = new Metadata();
>                     var passwordKey = Key.of(PASSWORD_KEY,
> ASCII_STRING_MARSHALLER);
>                     headers.put(passwordKey, passwordValue);
>                     metadataApplier.apply(headers);
>                } catch (Throwable ex) {
>                     metadataApplier.fail(UNAUTHENTICATED.withCause(ex));
>                }
>            });
>      }
>      @Override
>      public void thisUsesUnstableApi() {
>      }
> }
>
> If I understand correctly, PasswordCallCredentials is subclassing
> CallCredentials, and when called, it causes the key-value pair "password:
> {apiPasswordHere}" to be placed in the header of every gRPC request. If my
> understanding is wrong, please correct me.
>
> I have tested the Java client, and it works perfectly.
>
> Unfortunately, even after thoroughly searching through the documentation,
> I do not understand how to implement this in Python. I know I need to
> create a grpc.secure_channel and pass a ChannelCredentials object, but I'm
> not sure how to proceed from there. Can someone help me?
>
> --
> You received this message because you are subscribed to the Google Groups "
> grpc.io" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to grpc-io+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/grpc-io/eec9603c-2dc5-45a4-bfd1-f0d5ef796059n%40googlegroups.com
> <https://groups.google.com/d/msgid/grpc-io/eec9603c-2dc5-45a4-bfd1-f0d5ef796059n%40googlegroups.com?utm_medium=email&utm_source=footer>
> .
>

-- 
You received this message because you are subscribed to the Google Groups 
"grpc.io" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to grpc-io+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/grpc-io/CA%2BPad6hWrAr9kPzWNaPfW79xvX_z6iFv7BG%2Bb2VG8KjUuXGN8Q%40mail.gmail.com.

Reply via email to