浏览代码

Make APIs experimental

Richard Belleville 5 年之前
父节点
当前提交
ac864c7502

+ 2 - 13
src/python/grpcio/grpc/__init__.py

@@ -569,6 +569,7 @@ class StreamStreamClientInterceptor(six.with_metaclass(abc.ABCMeta)):
 
 ############  Authentication & Authorization Interfaces & Classes  #############
 
+
 class ChannelCredentials(object):
     """An encapsulation of the data required to create a secure Channel.
 
@@ -599,13 +600,6 @@ class CallCredentials(object):
         self._credentials = credentials
 
 
-_insecure_channel_credentials = object()
-
-
-def insecure_channel_credentials():
-    return ChannelCredentials(_insecure_channel_credentials)
-
-
 class AuthMetadataContext(six.with_metaclass(abc.ABCMeta)):
     """Provides information to call credentials metadata plugins.
 
@@ -1885,6 +1879,7 @@ def secure_channel(target, credentials, options=None, compression=None):
       A Channel.
     """
     from grpc import _channel  # pylint: disable=cyclic-import
+    from grpc.experimental import _insecure_channel_credentials
     if credentials._credentials is _insecure_channel_credentials:
         raise ValueError(
             "secure_channel cannot be called with insecure credentials." +
@@ -2031,7 +2026,6 @@ __all__ = (
     'access_token_call_credentials',
     'composite_call_credentials',
     'composite_channel_credentials',
-    'insecure_channel_credentials',
     'local_channel_credentials',
     'local_server_credentials',
     'ssl_server_credentials',
@@ -2042,13 +2036,8 @@ __all__ = (
     'secure_channel',
     'intercept_channel',
     'server',
-    'unary_unary',
 )
 
-if sys.version_info[0] >= 3:
-    from grpc._simple_stubs import unary_unary, unary_stream, stream_unary, stream_stream
-    __all__ = __all__ + (unary_unary, unary_stream, stream_unary, stream_stream)
-
 ############################### Extension Shims ################################
 
 # Here to maintain backwards compatibility; avoid using these in new code!

+ 18 - 8
src/python/grpcio/grpc/_simple_stubs.py

@@ -29,9 +29,11 @@ else:
 
 
 def _create_channel(target: str, options: Sequence[Tuple[str, str]],
-                    channel_credentials: grpc.ChannelCredentials,
+                    channel_credentials: Optional[grpc.ChannelCredentials],
                     compression: Optional[grpc.Compression]) -> grpc.Channel:
-    if channel_credentials._credentials is grpc._insecure_channel_credentials:
+    channel_credentials = channel_credentials or grpc.local_channel_credentials(
+    )
+    if channel_credentials._credentials is grpc.experimental._insecure_channel_credentials:
         _LOGGER.info(f"Creating insecure channel with options '{options}' " +
                      f"and compression '{compression}'")
         return grpc.insecure_channel(target,
@@ -98,7 +100,7 @@ class ChannelCache:
                         ChannelCache._condition.wait(timeout=time_to_eviction)
 
     def get_channel(self, target: str, options: Sequence[Tuple[str, str]],
-                    channel_credentials: grpc.ChannelCredentials,
+                    channel_credentials: Optional[grpc.ChannelCredentials],
                     compression: Optional[grpc.Compression]) -> grpc.Channel:
         key = (target, options, channel_credentials, compression)
         with self._lock:
@@ -128,7 +130,6 @@ class ChannelCache:
 RequestType = TypeVar('RequestType')
 ResponseType = TypeVar('ResponseType')
 
-
 # TODO(rbellevi): Consider a credential type that has the
 #   following functionality matrix:
 #
@@ -141,6 +142,7 @@ ResponseType = TypeVar('ResponseType')
 #
 #  Make this the default option.
 
+
 # TODO: Make LocalChannelCredentials the default.
 def unary_unary(
         request: RequestType,
@@ -158,6 +160,8 @@ def unary_unary(
 ) -> ResponseType:
     """Invokes a unary-unary RPC without an explicitly specified channel.
 
+    THIS IS AN EXPERIMENTAL API.
+
     This is backed by a per-process cache of channels. Channels are evicted
     from the cache after a fixed period by a background. Channels will also be
     evicted if more than a configured maximum accumulate.
@@ -199,7 +203,7 @@ def unary_unary(
     Returns:
       The response to the RPC.
     """
-    channel_credentials = channel_credentials or grpc.local_channel_credentials()
+    grpc.experimental.warn_experimental("unary_unary")
     channel = ChannelCache.get().get_channel(target, options,
                                              channel_credentials, compression)
     multicallable = channel.unary_unary(method, request_serializer,
@@ -227,6 +231,8 @@ def unary_stream(
 ) -> Iterator[ResponseType]:
     """Invokes a unary-stream RPC without an explicitly specified channel.
 
+    THIS IS AN EXPERIMENTAL API.
+
     This is backed by a per-process cache of channels. Channels are evicted
     from the cache after a fixed period by a background. Channels will also be
     evicted if more than a configured maximum accumulate.
@@ -267,7 +273,7 @@ def unary_stream(
     Returns:
       An iterator of responses.
     """
-    channel_credentials = channel_credentials or grpc.local_channel_credentials()
+    grpc.experimental.warn_experimental("unary_stream")
     channel = ChannelCache.get().get_channel(target, options,
                                              channel_credentials, compression)
     multicallable = channel.unary_stream(method, request_serializer,
@@ -295,6 +301,8 @@ def stream_unary(
 ) -> ResponseType:
     """Invokes a stream-unary RPC without an explicitly specified channel.
 
+    THIS IS AN EXPERIMENTAL API.
+
     This is backed by a per-process cache of channels. Channels are evicted
     from the cache after a fixed period by a background. Channels will also be
     evicted if more than a configured maximum accumulate.
@@ -335,7 +343,7 @@ def stream_unary(
     Returns:
       The response to the RPC.
     """
-    channel_credentials = channel_credentials or grpc.local_channel_credentials()
+    grpc.experimental.warn_experimental("stream_unary")
     channel = ChannelCache.get().get_channel(target, options,
                                              channel_credentials, compression)
     multicallable = channel.stream_unary(method, request_serializer,
@@ -363,6 +371,8 @@ def stream_stream(
 ) -> Iterator[ResponseType]:
     """Invokes a stream-stream RPC without an explicitly specified channel.
 
+    THIS IS AN EXPERIMENTAL API.
+
     This is backed by a per-process cache of channels. Channels are evicted
     from the cache after a fixed period by a background. Channels will also be
     evicted if more than a configured maximum accumulate.
@@ -403,7 +413,7 @@ def stream_stream(
     Returns:
       An iterator of responses.
     """
-    channel_credentials = channel_credentials or grpc.local_channel_credentials()
+    grpc.experimental.warn_experimental("stream_stream")
     channel = ChannelCache.get().get_channel(target, options,
                                              channel_credentials, compression)
     multicallable = channel.stream_stream(method, request_serializer,

+ 42 - 0
src/python/grpcio/grpc/experimental/__init__.py

@@ -16,6 +16,12 @@
 These APIs are subject to be removed during any minor version release.
 """
 
+import sys
+import warnings
+
+import grpc
+import grpc._simple_stubs
+
 
 class ChannelOptions(object):
     """Indicates a channel option unique to gRPC Python.
@@ -30,3 +36,39 @@ class ChannelOptions(object):
 
 class UsageError(Exception):
     """Raised by the gRPC library to indicate usage not allowed by the API."""
+
+
+_insecure_channel_credentials = object()
+
+
+def insecure_channel_credentials():
+    """Creates a ChannelCredentials for use with an insecure channel.
+
+    THIS IS AN EXPERIMENTAL API.
+
+    This is not for use with secure_channel function. Intead, this should be
+    used with grpc.unary_unary, grpc.unary_stream, grpc.stream_unary, or
+    grpc.stream_stream.
+    """
+    return grpc.ChannelCredentials(_insecure_channel_credentials)
+
+
+class ExperimentalApiWarning(Warning):
+    """A warning that an API is experimental."""
+
+def warn_experimental(api_name):
+    msg = ("{} is an experimental API. It is subject to change or ".format(api_name) +
+           "removal between minor releases. Proceed with caution.")
+    warnings.warn(msg, ExperimentalApiWarning, stacklevel=2)
+
+__all__ = (
+    'ChannelOptions',
+    'ExperimentalApiWarning',
+    'UsageError',
+    'insecure_channel_credentials',
+)
+
+if sys.version_info[0] >= 3:
+    from grpc._simple_stubs import unary_unary, unary_stream, stream_unary, stream_stream
+    __all__ = __all__ + (unary_unary, unary_stream, stream_unary, stream_stream)
+

+ 14 - 16
src/python/grpcio_tests/tests/unit/py3_only/_simple_stubs_test.py

@@ -31,6 +31,7 @@ from typing import Callable, Optional
 
 import test_common
 import grpc
+import grpc.experimental
 
 _REQUEST = b"0000"
 
@@ -151,17 +152,17 @@ class SimpleStubsTest(unittest.TestCase):
     def test_unary_unary_insecure(self):
         with _server(None) as (_, port):
             target = f'localhost:{port}'
-            response = grpc.unary_unary(
-                        _REQUEST,
-                        target,
-                        _UNARY_UNARY,
-                        channel_credentials=grpc.insecure_channel_credentials())
+            response = grpc.experimental.unary_unary(
+                _REQUEST,
+                target,
+                _UNARY_UNARY,
+                channel_credentials=grpc.experimental.insecure_channel_credentials())
             self.assertEqual(_REQUEST, response)
 
     def test_unary_unary_secure(self):
         with _server(grpc.local_server_credentials()) as (_, port):
             target = f'localhost:{port}'
-            response = grpc.unary_unary(
+            response = grpc.experimental.unary_unary(
                 _REQUEST,
                 target,
                 _UNARY_UNARY,
@@ -171,10 +172,7 @@ class SimpleStubsTest(unittest.TestCase):
     def test_channel_credentials_default(self):
         with _server(grpc.local_server_credentials()) as (_, port):
             target = f'localhost:{port}'
-            response = grpc.unary_unary(
-                _REQUEST,
-                target,
-                _UNARY_UNARY)
+            response = grpc.experimental.unary_unary(_REQUEST, target, _UNARY_UNARY)
             self.assertEqual(_REQUEST, response)
 
     def test_channels_cached(self):
@@ -187,14 +185,14 @@ class SimpleStubsTest(unittest.TestCase):
             def _invoke(seed: str):
                 run_kwargs = dict(kwargs)
                 run_kwargs["options"] = ((test_name + seed, ""),)
-                grpc.unary_unary(*args, **run_kwargs)
+                grpc.experimental.unary_unary(*args, **run_kwargs)
 
             self.assert_cached(_invoke)
 
     def test_channels_evicted(self):
         with _server(grpc.local_server_credentials()) as (_, port):
             target = f'localhost:{port}'
-            response = grpc.unary_unary(
+            response = grpc.experimental.unary_unary(
                 _REQUEST,
                 target,
                 _UNARY_UNARY,
@@ -213,7 +211,7 @@ class SimpleStubsTest(unittest.TestCase):
                 # Ensure we get a new channel each time.
                 options = (("foo", str(i)),)
                 # Send messages at full blast.
-                grpc.unary_unary(
+                grpc.experimental.unary_unary(
                     _REQUEST,
                     target,
                     _UNARY_UNARY,
@@ -229,7 +227,7 @@ class SimpleStubsTest(unittest.TestCase):
     def test_unary_stream(self):
         with _server(grpc.local_server_credentials()) as (_, port):
             target = f'localhost:{port}'
-            for response in grpc.unary_stream(
+            for response in grpc.experimental.unary_stream(
                     _REQUEST,
                     target,
                     _UNARY_STREAM,
@@ -244,7 +242,7 @@ class SimpleStubsTest(unittest.TestCase):
 
         with _server(grpc.local_server_credentials()) as (_, port):
             target = f'localhost:{port}'
-            response = grpc.stream_unary(
+            response = grpc.experimental.stream_unary(
                 request_iter(),
                 target,
                 _STREAM_UNARY,
@@ -259,7 +257,7 @@ class SimpleStubsTest(unittest.TestCase):
 
         with _server(grpc.local_server_credentials()) as (_, port):
             target = f'localhost:{port}'
-            for response in grpc.stream_stream(
+            for response in grpc.experimental.stream_stream(
                     request_iter(),
                     target,
                     _STREAM_STREAM,