Skip to content

Commit f96afd0

Browse files
author
Jon Wayne Parrott
authored
Add grpc_helpers.create_channel (#4069)
* Add grpc_helpers.create_channel * Fix import order
1 parent ff3b9a9 commit f96afd0

File tree

2 files changed

+70
-0
lines changed

2 files changed

+70
-0
lines changed

packages/google-cloud-core/google/api/core/helpers/grpc_helpers.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@
1818
import six
1919

2020
from google.api.core import exceptions
21+
import google.auth
22+
import google.auth.transport.grpc
23+
import google.auth.transport.requests
2124

2225

2326
# The list of gRPC Callable interfaces that return iterators.
@@ -102,3 +105,29 @@ def wrap_errors(callable_):
102105
return _wrap_stream_errors(callable_)
103106
else:
104107
return _wrap_unary_errors(callable_)
108+
109+
110+
def create_channel(target, credentials=None, scopes=None, **kwargs):
111+
"""Create a secure channel with credentials.
112+
113+
Args:
114+
target (str): The target service address in the format 'hostname:port'.
115+
credentials (google.auth.credentials.Credentials): The credentials. If
116+
not specified, then this function will attempt to ascertain the
117+
credentials from the environment using :func:`google.auth.default`.
118+
scopes (Sequence[str]): A optional list of scopes needed for this
119+
service. These are only used when credentials are not specified and
120+
are passed to :func:`google.auth.default`.
121+
kwargs: Additional key-word args passed to
122+
:func:`google.auth.transport.grpc.secure_authorized_channel`.
123+
124+
Returns:
125+
grpc.Channel: The created channel.
126+
"""
127+
if credentials is None:
128+
credentials, _ = google.auth.default(scopes=scopes)
129+
130+
request = google.auth.transport.requests.Request()
131+
132+
return google.auth.transport.grpc.secure_authorized_channel(
133+
credentials, request, target, **kwargs)

packages/google-cloud-core/tests/unit/api_core/helpers/test_grpc_helpers.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,3 +128,44 @@ def test_wrap_errors_streaming(wrap_stream_errors):
128128

129129
assert result == wrap_stream_errors.return_value
130130
wrap_stream_errors.assert_called_once_with(callable_)
131+
132+
133+
@mock.patch(
134+
'google.auth.default',
135+
return_value=(mock.sentinel.credentials, mock.sentinel.projet))
136+
@mock.patch('google.auth.transport.grpc.secure_authorized_channel')
137+
def test_create_channel_implicit(secure_authorized_channel, default):
138+
target = 'example.com:443'
139+
140+
channel = grpc_helpers.create_channel(target)
141+
142+
assert channel is secure_authorized_channel.return_value
143+
default.assert_called_once_with(scopes=None)
144+
secure_authorized_channel.assert_called_once_with(
145+
mock.sentinel.credentials, mock.ANY, target)
146+
147+
148+
@mock.patch(
149+
'google.auth.default',
150+
return_value=(mock.sentinel.credentials, mock.sentinel.projet))
151+
@mock.patch('google.auth.transport.grpc.secure_authorized_channel')
152+
def test_create_channel_implicit_with_scopes(
153+
secure_authorized_channel, default):
154+
target = 'example.com:443'
155+
156+
channel = grpc_helpers.create_channel(target, scopes=['one', 'two'])
157+
158+
assert channel is secure_authorized_channel.return_value
159+
default.assert_called_once_with(scopes=['one', 'two'])
160+
161+
162+
@mock.patch('google.auth.transport.grpc.secure_authorized_channel')
163+
def test_create_channel_explicit(secure_authorized_channel):
164+
target = 'example.com:443'
165+
166+
channel = grpc_helpers.create_channel(
167+
target, credentials=mock.sentinel.credentials)
168+
169+
assert channel is secure_authorized_channel.return_value
170+
secure_authorized_channel.assert_called_once_with(
171+
mock.sentinel.credentials, mock.ANY, target)

0 commit comments

Comments
 (0)