diff --git a/src/python/grpcio/grpc/beta/_client_adaptations.py b/src/python/grpcio/grpc/beta/_client_adaptations.py index 73ce22fa981..dcaa0eeaa29 100644 --- a/src/python/grpcio/grpc/beta/_client_adaptations.py +++ b/src/python/grpcio/grpc/beta/_client_adaptations.py @@ -15,6 +15,7 @@ import grpc from grpc import _common +from grpc.beta import _metadata from grpc.beta import interfaces from grpc.framework.common import cardinality from grpc.framework.foundation import future @@ -157,10 +158,10 @@ class _Rendezvous(future.Future, face.Call): return _InvocationProtocolContext() def initial_metadata(self): - return self._call.initial_metadata() + return _metadata.beta(self._call.initial_metadata()) def terminal_metadata(self): - return self._call.terminal_metadata() + return _metadata.beta(self._call.terminal_metadata()) def code(self): return self._call.code() @@ -182,14 +183,14 @@ def _blocking_unary_unary(channel, group, method, timeout, with_call, response, call = multi_callable.with_call( request, timeout=timeout, - metadata=effective_metadata, + metadata=_metadata.unbeta(effective_metadata), credentials=_credentials(protocol_options)) return response, _Rendezvous(None, None, call) else: return multi_callable( request, timeout=timeout, - metadata=effective_metadata, + metadata=_metadata.unbeta(effective_metadata), credentials=_credentials(protocol_options)) except grpc.RpcError as rpc_error_call: raise _abortion_error(rpc_error_call) @@ -206,7 +207,7 @@ def _future_unary_unary(channel, group, method, timeout, protocol_options, response_future = multi_callable.future( request, timeout=timeout, - metadata=effective_metadata, + metadata=_metadata.unbeta(effective_metadata), credentials=_credentials(protocol_options)) return _Rendezvous(response_future, None, response_future) @@ -222,7 +223,7 @@ def _unary_stream(channel, group, method, timeout, protocol_options, metadata, response_iterator = multi_callable( request, timeout=timeout, - metadata=effective_metadata, + metadata=_metadata.unbeta(effective_metadata), credentials=_credentials(protocol_options)) return _Rendezvous(None, response_iterator, response_iterator) @@ -241,14 +242,14 @@ def _blocking_stream_unary(channel, group, method, timeout, with_call, response, call = multi_callable.with_call( request_iterator, timeout=timeout, - metadata=effective_metadata, + metadata=_metadata.unbeta(effective_metadata), credentials=_credentials(protocol_options)) return response, _Rendezvous(None, None, call) else: return multi_callable( request_iterator, timeout=timeout, - metadata=effective_metadata, + metadata=_metadata.unbeta(effective_metadata), credentials=_credentials(protocol_options)) except grpc.RpcError as rpc_error_call: raise _abortion_error(rpc_error_call) @@ -265,7 +266,7 @@ def _future_stream_unary(channel, group, method, timeout, protocol_options, response_future = multi_callable.future( request_iterator, timeout=timeout, - metadata=effective_metadata, + metadata=_metadata.unbeta(effective_metadata), credentials=_credentials(protocol_options)) return _Rendezvous(response_future, None, response_future) @@ -281,7 +282,7 @@ def _stream_stream(channel, group, method, timeout, protocol_options, metadata, response_iterator = multi_callable( request_iterator, timeout=timeout, - metadata=effective_metadata, + metadata=_metadata.unbeta(effective_metadata), credentials=_credentials(protocol_options)) return _Rendezvous(None, response_iterator, response_iterator) diff --git a/src/python/grpcio/grpc/beta/_metadata.py b/src/python/grpcio/grpc/beta/_metadata.py new file mode 100644 index 00000000000..e135f4dff4f --- /dev/null +++ b/src/python/grpcio/grpc/beta/_metadata.py @@ -0,0 +1,49 @@ +# Copyright 2017 gRPC authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""API metadata conversion utilities.""" + +import collections + +_Metadatum = collections.namedtuple('_Metadatum', ('key', 'value',)) + + +def _beta_metadatum(key, value): + beta_key = key if isinstance(key, (bytes,)) else key.encode('ascii') + beta_value = value if isinstance(value, (bytes,)) else value.encode('ascii') + return _Metadatum(beta_key, beta_value) + + +def _metadatum(beta_key, beta_value): + key = beta_key if isinstance(beta_key, (str,)) else beta_key.decode('utf8') + if isinstance(beta_value, (str,)) or key[-4:] == '-bin': + value = beta_value + else: + value = beta_value.decode('utf8') + return _Metadatum(key, value) + + +def beta(metadata): + if metadata is None: + return () + else: + return tuple(_beta_metadatum(key, value) for key, value in metadata) + + +def unbeta(beta_metadata): + if beta_metadata is None: + return () + else: + return tuple( + _metadatum(beta_key, beta_value) + for beta_key, beta_value in beta_metadata) diff --git a/src/python/grpcio/grpc/beta/_server_adaptations.py b/src/python/grpcio/grpc/beta/_server_adaptations.py index ec363e9bc93..1c22dbe3bbe 100644 --- a/src/python/grpcio/grpc/beta/_server_adaptations.py +++ b/src/python/grpcio/grpc/beta/_server_adaptations.py @@ -18,6 +18,7 @@ import threading import grpc from grpc import _common +from grpc.beta import _metadata from grpc.beta import interfaces from grpc.framework.common import cardinality from grpc.framework.common import style @@ -65,14 +66,15 @@ class _FaceServicerContext(face.ServicerContext): return _ServerProtocolContext(self._servicer_context) def invocation_metadata(self): - return _common.to_cygrpc_metadata( - self._servicer_context.invocation_metadata()) + return _metadata.beta(self._servicer_context.invocation_metadata()) def initial_metadata(self, initial_metadata): - self._servicer_context.send_initial_metadata(initial_metadata) + self._servicer_context.send_initial_metadata( + _metadata.unbeta(initial_metadata)) def terminal_metadata(self, terminal_metadata): - self._servicer_context.set_terminal_metadata(terminal_metadata) + self._servicer_context.set_terminal_metadata( + _metadata.unbeta(terminal_metadata)) def code(self, code): self._servicer_context.set_code(code) diff --git a/src/python/grpcio/grpc/beta/implementations.py b/src/python/grpcio/grpc/beta/implementations.py index e52ce764b5a..312daf033e3 100644 --- a/src/python/grpcio/grpc/beta/implementations.py +++ b/src/python/grpcio/grpc/beta/implementations.py @@ -21,6 +21,7 @@ import threading # pylint: disable=unused-import import grpc from grpc import _auth from grpc.beta import _client_adaptations +from grpc.beta import _metadata from grpc.beta import _server_adaptations from grpc.beta import interfaces # pylint: disable=unused-import from grpc.framework.common import cardinality # pylint: disable=unused-import @@ -31,7 +32,18 @@ from grpc.framework.interfaces.face import face # pylint: disable=unused-import ChannelCredentials = grpc.ChannelCredentials ssl_channel_credentials = grpc.ssl_channel_credentials CallCredentials = grpc.CallCredentials -metadata_call_credentials = grpc.metadata_call_credentials + + +def metadata_call_credentials(metadata_plugin, name=None): + + def plugin(context, callback): + + def wrapped_callback(beta_metadata, error): + callback(_metadata.unbeta(beta_metadata), error) + + metadata_plugin(context, wrapped_callback) + + return grpc.metadata_call_credentials(plugin, name=name) def google_call_credentials(credentials):