Skip to content

Commit 51a64f2

Browse files
authored
Merge pull request #2082 from dhermes/move-bigtable-stub-helper-into-general
Moving gRPC stub-with-auth helpers out of bigtable package.
2 parents 6c49c54 + 8bdf12c commit 51a64f2

File tree

4 files changed

+228
-206
lines changed

4 files changed

+228
-206
lines changed

gcloud/_helpers.py

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@
2929
from google.appengine.api import app_identity
3030
except ImportError:
3131
app_identity = None
32+
try:
33+
from grpc.beta import implementations
34+
except ImportError: # pragma: NO COVER
35+
implementations = None
3236
import six
3337
from six.moves.http_client import HTTPConnection
3438
from six.moves import configparser
@@ -522,6 +526,76 @@ def _name_from_project_path(path, project, template):
522526
return match.group('name')
523527

524528

529+
class MetadataPlugin(object):
530+
"""Callable class to transform metadata for gRPC requests.
531+
532+
:type credentials: :class:`oauth2client.client.OAuth2Credentials`
533+
:param credentials: The OAuth2 Credentials to use for creating
534+
access tokens.
535+
536+
:type user_agent: str
537+
:param user_agent: The user agent to be used with API requests.
538+
"""
539+
540+
def __init__(self, credentials, user_agent):
541+
self._credentials = credentials
542+
self._user_agent = user_agent
543+
544+
def __call__(self, unused_context, callback):
545+
"""Adds authorization header to request metadata.
546+
547+
:type unused_context: object
548+
:param unused_context: A gRPC context which is not needed
549+
to modify headers.
550+
551+
:type callback: callable
552+
:param callback: A callback which will use the headers.
553+
"""
554+
access_token = self._credentials.get_access_token().access_token
555+
headers = [
556+
('Authorization', 'Bearer ' + access_token),
557+
('User-agent', self._user_agent),
558+
]
559+
callback(headers, None)
560+
561+
562+
def make_stub(credentials, user_agent, stub_factory, host, port):
563+
"""Makes a stub for an RPC service.
564+
565+
Uses / depends on the beta implementation of gRPC.
566+
567+
:type credentials: :class:`oauth2client.client.OAuth2Credentials`
568+
:param credentials: The OAuth2 Credentials to use for creating
569+
access tokens.
570+
571+
:type user_agent: str
572+
:param user_agent: (Optional) The user agent to be used with API requests.
573+
574+
:type stub_factory: callable
575+
:param stub_factory: A factory which will create a gRPC stub for
576+
a given service.
577+
578+
:type host: str
579+
:param host: The host for the service.
580+
581+
:type port: int
582+
:param port: The port for the service.
583+
584+
:rtype: :class:`grpc.beta._stub._AutoIntermediary`
585+
:returns: The stub object used to make gRPC requests to a given API.
586+
"""
587+
# Leaving the first argument to ssl_channel_credentials() as None
588+
# loads root certificates from `grpc/_adapter/credentials/roots.pem`.
589+
transport_creds = implementations.ssl_channel_credentials(None, None, None)
590+
custom_metadata_plugin = MetadataPlugin(credentials, user_agent)
591+
auth_creds = implementations.metadata_call_credentials(
592+
custom_metadata_plugin, name='google_creds')
593+
channel_creds = implementations.composite_channel_credentials(
594+
transport_creds, auth_creds)
595+
channel = implementations.secure_channel(host, port, channel_creds)
596+
return stub_factory(channel)
597+
598+
525599
try:
526600
from pytz import UTC # pylint: disable=unused-import,wrong-import-order
527601
except ImportError:

gcloud/bigtable/client.py

Lines changed: 13 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929

3030
from pkg_resources import get_distribution
3131

32-
from grpc.beta import implementations
32+
from gcloud._helpers import make_stub
3333

3434
from gcloud.bigtable._generated import (
3535
bigtable_instance_admin_pb2 as instance_admin_v2_pb2)
@@ -284,17 +284,19 @@ def _make_data_stub(self):
284284
:rtype: :class:`grpc.beta._stub._AutoIntermediary`
285285
:returns: A gRPC stub object.
286286
"""
287-
return _make_stub(self, DATA_STUB_FACTORY_V2,
288-
DATA_API_HOST_V2, DATA_API_PORT_V2)
287+
return make_stub(self.credentials, self.user_agent,
288+
DATA_STUB_FACTORY_V2, DATA_API_HOST_V2,
289+
DATA_API_PORT_V2)
289290

290291
def _make_instance_stub(self):
291292
"""Creates gRPC stub to make requests to the Instance Admin API.
292293
293294
:rtype: :class:`grpc.beta._stub._AutoIntermediary`
294295
:returns: A gRPC stub object.
295296
"""
296-
return _make_stub(self, INSTANCE_STUB_FACTORY_V2,
297-
INSTANCE_ADMIN_HOST_V2, INSTANCE_ADMIN_PORT_V2)
297+
return make_stub(self.credentials, self.user_agent,
298+
INSTANCE_STUB_FACTORY_V2, INSTANCE_ADMIN_HOST_V2,
299+
INSTANCE_ADMIN_PORT_V2)
298300

299301
def _make_operations_stub(self):
300302
"""Creates gRPC stub to make requests to the Operations API.
@@ -305,17 +307,19 @@ def _make_operations_stub(self):
305307
:rtype: :class:`grpc.beta._stub._AutoIntermediary`
306308
:returns: A gRPC stub object.
307309
"""
308-
return _make_stub(self, OPERATIONS_STUB_FACTORY_V2,
309-
OPERATIONS_API_HOST_V2, OPERATIONS_API_PORT_V2)
310+
return make_stub(self.credentials, self.user_agent,
311+
OPERATIONS_STUB_FACTORY_V2, OPERATIONS_API_HOST_V2,
312+
OPERATIONS_API_PORT_V2)
310313

311314
def _make_table_stub(self):
312315
"""Creates gRPC stub to make requests to the Table Admin API.
313316
314317
:rtype: :class:`grpc.beta._stub._AutoIntermediary`
315318
:returns: A gRPC stub object.
316319
"""
317-
return _make_stub(self, TABLE_STUB_FACTORY_V2,
318-
TABLE_ADMIN_HOST_V2, TABLE_ADMIN_PORT_V2)
320+
return make_stub(self.credentials, self.user_agent,
321+
TABLE_STUB_FACTORY_V2, TABLE_ADMIN_HOST_V2,
322+
TABLE_ADMIN_PORT_V2)
319323

320324
def is_started(self):
321325
"""Check if the client has been started.
@@ -422,59 +426,3 @@ def list_instances(self):
422426
instances = [Instance.from_pb(instance_pb, self)
423427
for instance_pb in response.instances]
424428
return instances, response.failed_locations
425-
426-
427-
class _MetadataPlugin(object):
428-
"""Callable class to transform metadata for gRPC requests.
429-
430-
:type client: :class:`.client.Client`
431-
:param client: The client that owns the instance.
432-
Provides authorization and user agent.
433-
"""
434-
435-
def __init__(self, client):
436-
self._credentials = client.credentials
437-
self._user_agent = client.user_agent
438-
439-
def __call__(self, unused_context, callback):
440-
"""Adds authorization header to request metadata."""
441-
access_token = self._credentials.get_access_token().access_token
442-
headers = [
443-
('Authorization', 'Bearer ' + access_token),
444-
('User-agent', self._user_agent),
445-
]
446-
callback(headers, None)
447-
448-
449-
def _make_stub(client, stub_factory, host, port):
450-
"""Makes a stub for an RPC service.
451-
452-
Uses / depends on the beta implementation of gRPC.
453-
454-
:type client: :class:`.client.Client`
455-
:param client: The client that owns the instance.
456-
Provides authorization and user agent.
457-
458-
:type stub_factory: callable
459-
:param stub_factory: A factory which will create a gRPC stub for
460-
a given service.
461-
462-
:type host: str
463-
:param host: The host for the service.
464-
465-
:type port: int
466-
:param port: The port for the service.
467-
468-
:rtype: :class:`grpc.beta._stub._AutoIntermediary`
469-
:returns: The stub object used to make gRPC requests to a given API.
470-
"""
471-
# Leaving the first argument to ssl_channel_credentials() as None
472-
# loads root certificates from `grpc/_adapter/credentials/roots.pem`.
473-
transport_creds = implementations.ssl_channel_credentials(None, None, None)
474-
custom_metadata_plugin = _MetadataPlugin(client)
475-
auth_creds = implementations.metadata_call_credentials(
476-
custom_metadata_plugin, name='google_creds')
477-
channel_creds = implementations.composite_channel_credentials(
478-
transport_creds, auth_creds)
479-
channel = implementations.secure_channel(host, port, channel_creds)
480-
return stub_factory(channel)

0 commit comments

Comments
 (0)