Dan Jenson
Dan Jenson

Reputation: 1041

python gRPC equivalent of golang's PerRPCCredentials

I've implemented a gRPC server in golang that requires custom authorization information, i.e. email and api_key (over a TLS-encrypted connection). In golang, I can easily implement the client using PerRPCCredentials, which simply creates a metadata map like {"email": email, "api_key": apiKey}. (Then I use a StreamInterceptor on the server side to extract them from the incoming context and then validate them). However, I can't figure out how to do the equivalent for a python client. I have tried implementing an AuthMetadataPlugin as documented here https://github.com/grpc/grpc/tree/master/examples/python/auth and exemplified here: https://github.com/grpc/grpc/blob/master/examples/python/auth/customized_auth_client.py

class AuthMetadataPlugin:
  def __init__(self, email, api_key):
    self.email = email
    self.api_key = api_key
  def __call__(self, context, callback):
    callback((('email', self.email), ('api_key', self.api_key)), None)

But I get the following error: TypeError: Cannot convert grpc._cython.cygrpc.MetadataPluginCallCredentials to grpc._cython.cygrpc.ChannelCredentials when I call grpc.metadata_call_credentials(AuthMetadataPlugin(email, api_key)).

What's more confusing is that a lot of the documentation seems to talk about adding custom HTTP headers, but I only want this authorization information to be sent once per (streaming) RPC call, not with every HTTP frame for these calls. (Admittedly, I'm not sure how it works in golang, but I do know my StreamInterceptor is only called once per streaming RPC call).

How can I add this authorization information to my RPC calls in python so that my golang gRPC server can pull it out of the incoming context?

Upvotes: 2

Views: 1128

Answers (1)

Dan Jenson
Dan Jenson

Reputation: 1041

That actually worked, I was passing the credentials to the composite composer in the wrong order - tls credentials must come first.

Upvotes: 0

Related Questions