1# Copyright 2015-2016 gRPC authors.
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7#     http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14"""Entry points into the Beta API of gRPC Python."""
15
16# threading is referenced from specification in this module.
17import threading  # pylint: disable=unused-import
18
19# interfaces, cardinality, and face are referenced from specification in this
20# module.
21import grpc
22from grpc import _auth
23from grpc.beta import _client_adaptations
24from grpc.beta import _metadata
25from grpc.beta import _server_adaptations
26from grpc.beta import interfaces  # pylint: disable=unused-import
27from grpc.framework.common import cardinality  # pylint: disable=unused-import
28from grpc.framework.interfaces.face import \
29    face  # pylint: disable=unused-import
30
31# pylint: disable=too-many-arguments
32
33ChannelCredentials = grpc.ChannelCredentials
34ssl_channel_credentials = grpc.ssl_channel_credentials
35CallCredentials = grpc.CallCredentials
36
37
38def metadata_call_credentials(metadata_plugin, name=None):
39
40    def plugin(context, callback):
41
42        def wrapped_callback(beta_metadata, error):
43            callback(_metadata.unbeta(beta_metadata), error)
44
45        metadata_plugin(context, wrapped_callback)
46
47    return grpc.metadata_call_credentials(plugin, name=name)
48
49
50def google_call_credentials(credentials):
51    """Construct CallCredentials from GoogleCredentials.
52
53  Args:
54    credentials: A GoogleCredentials object from the oauth2client library.
55
56  Returns:
57    A CallCredentials object for use in a GRPCCallOptions object.
58  """
59    return metadata_call_credentials(_auth.GoogleCallCredentials(credentials))
60
61
62access_token_call_credentials = grpc.access_token_call_credentials
63composite_call_credentials = grpc.composite_call_credentials
64composite_channel_credentials = grpc.composite_channel_credentials
65
66
67class Channel(object):
68    """A channel to a remote host through which RPCs may be conducted.
69
70  Only the "subscribe" and "unsubscribe" methods are supported for application
71  use. This class' instance constructor and all other attributes are
72  unsupported.
73  """
74
75    def __init__(self, channel):
76        self._channel = channel
77
78    def subscribe(self, callback, try_to_connect=None):
79        """Subscribes to this Channel's connectivity.
80
81    Args:
82      callback: A callable to be invoked and passed an
83        interfaces.ChannelConnectivity identifying this Channel's connectivity.
84        The callable will be invoked immediately upon subscription and again for
85        every change to this Channel's connectivity thereafter until it is
86        unsubscribed.
87      try_to_connect: A boolean indicating whether or not this Channel should
88        attempt to connect if it is not already connected and ready to conduct
89        RPCs.
90    """
91        self._channel.subscribe(callback, try_to_connect=try_to_connect)
92
93    def unsubscribe(self, callback):
94        """Unsubscribes a callback from this Channel's connectivity.
95
96    Args:
97      callback: A callable previously registered with this Channel from having
98        been passed to its "subscribe" method.
99    """
100        self._channel.unsubscribe(callback)
101
102
103def insecure_channel(host, port):
104    """Creates an insecure Channel to a remote host.
105
106  Args:
107    host: The name of the remote host to which to connect.
108    port: The port of the remote host to which to connect.
109      If None only the 'host' part will be used.
110
111  Returns:
112    A Channel to the remote host through which RPCs may be conducted.
113  """
114    channel = grpc.insecure_channel(host if port is None else '%s:%d' %
115                                    (host, port))
116    return Channel(channel)
117
118
119def secure_channel(host, port, channel_credentials):
120    """Creates a secure Channel to a remote host.
121
122  Args:
123    host: The name of the remote host to which to connect.
124    port: The port of the remote host to which to connect.
125      If None only the 'host' part will be used.
126    channel_credentials: A ChannelCredentials.
127
128  Returns:
129    A secure Channel to the remote host through which RPCs may be conducted.
130  """
131    channel = grpc.secure_channel(
132        host if port is None else '%s:%d' % (host, port), channel_credentials)
133    return Channel(channel)
134
135
136class StubOptions(object):
137    """A value encapsulating the various options for creation of a Stub.
138
139  This class and its instances have no supported interface - it exists to define
140  the type of its instances and its instances exist to be passed to other
141  functions.
142  """
143
144    def __init__(self, host, request_serializers, response_deserializers,
145                 metadata_transformer, thread_pool, thread_pool_size):
146        self.host = host
147        self.request_serializers = request_serializers
148        self.response_deserializers = response_deserializers
149        self.metadata_transformer = metadata_transformer
150        self.thread_pool = thread_pool
151        self.thread_pool_size = thread_pool_size
152
153
154_EMPTY_STUB_OPTIONS = StubOptions(None, None, None, None, None, None)
155
156
157def stub_options(host=None,
158                 request_serializers=None,
159                 response_deserializers=None,
160                 metadata_transformer=None,
161                 thread_pool=None,
162                 thread_pool_size=None):
163    """Creates a StubOptions value to be passed at stub creation.
164
165  All parameters are optional and should always be passed by keyword.
166
167  Args:
168    host: A host string to set on RPC calls.
169    request_serializers: A dictionary from service name-method name pair to
170      request serialization behavior.
171    response_deserializers: A dictionary from service name-method name pair to
172      response deserialization behavior.
173    metadata_transformer: A callable that given a metadata object produces
174      another metadata object to be used in the underlying communication on the
175      wire.
176    thread_pool: A thread pool to use in stubs.
177    thread_pool_size: The size of thread pool to create for use in stubs;
178      ignored if thread_pool has been passed.
179
180  Returns:
181    A StubOptions value created from the passed parameters.
182  """
183    return StubOptions(host, request_serializers, response_deserializers,
184                       metadata_transformer, thread_pool, thread_pool_size)
185
186
187def generic_stub(channel, options=None):
188    """Creates a face.GenericStub on which RPCs can be made.
189
190  Args:
191    channel: A Channel for use by the created stub.
192    options: A StubOptions customizing the created stub.
193
194  Returns:
195    A face.GenericStub on which RPCs can be made.
196  """
197    effective_options = _EMPTY_STUB_OPTIONS if options is None else options
198    return _client_adaptations.generic_stub(
199        channel._channel,  # pylint: disable=protected-access
200        effective_options.host,
201        effective_options.metadata_transformer,
202        effective_options.request_serializers,
203        effective_options.response_deserializers)
204
205
206def dynamic_stub(channel, service, cardinalities, options=None):
207    """Creates a face.DynamicStub with which RPCs can be invoked.
208
209  Args:
210    channel: A Channel for the returned face.DynamicStub to use.
211    service: The package-qualified full name of the service.
212    cardinalities: A dictionary from RPC method name to cardinality.Cardinality
213      value identifying the cardinality of the RPC method.
214    options: An optional StubOptions value further customizing the functionality
215      of the returned face.DynamicStub.
216
217  Returns:
218    A face.DynamicStub with which RPCs can be invoked.
219  """
220    effective_options = _EMPTY_STUB_OPTIONS if options is None else options
221    return _client_adaptations.dynamic_stub(
222        channel._channel,  # pylint: disable=protected-access
223        service,
224        cardinalities,
225        effective_options.host,
226        effective_options.metadata_transformer,
227        effective_options.request_serializers,
228        effective_options.response_deserializers)
229
230
231ServerCredentials = grpc.ServerCredentials
232ssl_server_credentials = grpc.ssl_server_credentials
233
234
235class ServerOptions(object):
236    """A value encapsulating the various options for creation of a Server.
237
238  This class and its instances have no supported interface - it exists to define
239  the type of its instances and its instances exist to be passed to other
240  functions.
241  """
242
243    def __init__(self, multi_method_implementation, request_deserializers,
244                 response_serializers, thread_pool, thread_pool_size,
245                 default_timeout, maximum_timeout):
246        self.multi_method_implementation = multi_method_implementation
247        self.request_deserializers = request_deserializers
248        self.response_serializers = response_serializers
249        self.thread_pool = thread_pool
250        self.thread_pool_size = thread_pool_size
251        self.default_timeout = default_timeout
252        self.maximum_timeout = maximum_timeout
253
254
255_EMPTY_SERVER_OPTIONS = ServerOptions(None, None, None, None, None, None, None)
256
257
258def server_options(multi_method_implementation=None,
259                   request_deserializers=None,
260                   response_serializers=None,
261                   thread_pool=None,
262                   thread_pool_size=None,
263                   default_timeout=None,
264                   maximum_timeout=None):
265    """Creates a ServerOptions value to be passed at server creation.
266
267  All parameters are optional and should always be passed by keyword.
268
269  Args:
270    multi_method_implementation: A face.MultiMethodImplementation to be called
271      to service an RPC if the server has no specific method implementation for
272      the name of the RPC for which service was requested.
273    request_deserializers: A dictionary from service name-method name pair to
274      request deserialization behavior.
275    response_serializers: A dictionary from service name-method name pair to
276      response serialization behavior.
277    thread_pool: A thread pool to use in stubs.
278    thread_pool_size: The size of thread pool to create for use in stubs;
279      ignored if thread_pool has been passed.
280    default_timeout: A duration in seconds to allow for RPC service when
281      servicing RPCs that did not include a timeout value when invoked.
282    maximum_timeout: A duration in seconds to allow for RPC service when
283      servicing RPCs no matter what timeout value was passed when the RPC was
284      invoked.
285
286  Returns:
287    A StubOptions value created from the passed parameters.
288  """
289    return ServerOptions(multi_method_implementation, request_deserializers,
290                         response_serializers, thread_pool, thread_pool_size,
291                         default_timeout, maximum_timeout)
292
293
294def server(service_implementations, options=None):
295    """Creates an interfaces.Server with which RPCs can be serviced.
296
297  Args:
298    service_implementations: A dictionary from service name-method name pair to
299      face.MethodImplementation.
300    options: An optional ServerOptions value further customizing the
301      functionality of the returned Server.
302
303  Returns:
304    An interfaces.Server with which RPCs can be serviced.
305  """
306    effective_options = _EMPTY_SERVER_OPTIONS if options is None else options
307    return _server_adaptations.server(
308        service_implementations, effective_options.multi_method_implementation,
309        effective_options.request_deserializers,
310        effective_options.response_serializers, effective_options.thread_pool,
311        effective_options.thread_pool_size)
312