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.