Skip to content

Commit

Permalink
feat: port REST transport to Ads templates
Browse files Browse the repository at this point in the history
Add REST transport tests to Ads generated unit tests
Boost google-api-core dependency version
Minor bugfixes
  • Loading branch information
software-dov committed Sep 30, 2021
1 parent ccdd17d commit 4e687e7
Show file tree
Hide file tree
Showing 12 changed files with 477 additions and 52 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,13 @@ from google.oauth2 import service_account # type: ignore
{% endfor %}
{% endfor %}
{% endfilter %}
{% if 'grpc' in opts.transport %}
from .transports.base import {{ service.name }}Transport, DEFAULT_CLIENT_INFO
from .transports.grpc import {{ service.name }}GrpcTransport
{% endif %}
{% if 'rest' in opts.transport %}
from .transports.rest import {{ service.name }}RestTransport
{% endif %}


class {{ service.client_name }}Meta(type):
Expand All @@ -40,8 +45,13 @@ class {{ service.client_name }}Meta(type):
support objects (e.g. transport) without polluting the client instance
objects.
"""
{% if "grpc" in opts.transport %}
_transport_registry = OrderedDict() # type: Dict[str, Type[{{ service.name }}Transport]]
_transport_registry['grpc'] = {{ service.name }}GrpcTransport
{% endif %}
{% if "rest" in opts.transport %}
_transport_registry["rest"] = {{ service.name }}RestTransport
{% endif %}

def get_transport_class(cls,
label: str = None,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,29 @@ from collections import OrderedDict
from typing import Dict, Type

from .base import {{ service.name }}Transport
{% if 'grpc' in opts.transport %}
from .grpc import {{ service.name }}GrpcTransport

{% endif %}
{% if 'rest' in opts.transport %}
from .rest import {{ service.name }}RestTransport
{% endif %}

# Compile a registry of transports.
_transport_registry = OrderedDict() # type: Dict[str, Type[{{ service.name }}Transport]]
{% if 'grpc' in opts.transport %}
_transport_registry['grpc'] = {{ service.name }}GrpcTransport

{% endif %}
{% if 'rest' in opts.transport %}
_transport_registry['rest'] = {{ service.name }}RestTransport
{% endif %}

__all__ = (
'{{ service.name }}Transport',
{% if 'grpc' in opts.transport %}
'{{ service.name }}GrpcTransport',
{% endif %}
{% if 'rest' in opts.transport %}
'{{ service.name }}RestTransport',
{% endif %}
)
{% endblock %}
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,13 @@

import abc
import typing
import packaging.version
import pkg_resources
from typing import Dict, Optional, {% if service.any_server_streaming %}Iterable, {% endif %}{% if service.any_client_streaming %}Iterator, {% endif %}Sequence, Tuple, Type, Union

import google.auth # type: ignore
from google.api_core import gapic_v1 # type: ignore
from google.api_core import exceptions as core_exceptions # type: ignore
from google.api_core import retry as retries # type: ignore
{% if service.has_lro %}
from google.api_core import operations_v1 # type: ignore
Expand All @@ -30,6 +33,15 @@ try:
except pkg_resources.DistributionNotFound:
DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo()

try:
# google.auth.__version__ was added in 1.26.0
_GOOGLE_AUTH_VERSION = google.auth.__version__
except AttributeError:
try: # try pkg_resources if it is available
_GOOGLE_AUTH_VERSION = pkg_resources.get_distribution("google-auth").version
except pkg_resources.DistributionNotFound: # pragma: NO COVER
_GOOGLE_AUTH_VERSION = None


class {{ service.name }}Transport(metaclass=abc.ABCMeta):
"""Abstract transport class for {{ service.name }}."""
Expand All @@ -40,11 +52,17 @@ class {{ service.name }}Transport(metaclass=abc.ABCMeta):
{% endfor %}
)

DEFAULT_HOST: str = {% if service.host %}'{{ service.host }}'{% else %}{{ '' }}{% endif %}

def __init__(
self, *,
host: str{% if service.host %} = '{{ service.host }}'{% endif %},
credentials: ga_credentials.Credentials = None,
credentials_file: Optional[str] = None,
scopes: Optional[Sequence[str]] = None,
quota_project_id: Optional[str] = None,
client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO,
always_use_jwt_access: Optional[bool] = False,
) -> None:
"""Instantiate the transport.

Expand All @@ -56,17 +74,47 @@ class {{ service.name }}Transport(metaclass=abc.ABCMeta):
credentials identify the application to the service; if none
are specified, the client will attempt to ascertain the
credentials from the environment.
credentials_file (Optional[str]): A file with credentials that can
be loaded with :func:`google.auth.load_credentials_from_file`.
This argument is mutually exclusive with credentials.
scopes (Optional[Sequence[str]]): A list of scopes.
quota_project_id (Optional[str]): An optional project to use for billing
and quota.
client_info (google.api_core.gapic_v1.client_info.ClientInfo):
The client info used to send a user-agent string along with
API requests. If ``None``, then default info will be used.
Generally, you only need to set this if you're developing
your own client library.
always_use_jwt_access (Optional[bool]): Whether self signed JWT should
be used for service account credentials.
"""
# Save the hostname. Default to port 443 (HTTPS) if none is specified.
if ':' not in host:
host += ':443'
self._host = host

scopes_kwargs = self._get_scopes_kwargs(self._host, scopes)

# Save the scopes.
self._scopes = scopes

# If no credentials are provided, then determine the appropriate
# defaults.
if credentials and credentials_file:
raise core_exceptions.DuplicateCredentialArgs("'credentials_file' and 'credentials' are mutually exclusive")

if credentials_file is not None:
credentials, _ = google.auth.load_credentials_from_file(
credentials_file,
**scopes_kwargs,
quota_project_id=quota_project_id
)
elif credentials is None:
credentials, _ = google.auth.default(**scopes_kwargs, quota_project_id=quota_project_id)

if always_use_jwt_access and isinstance(credentials, service_account.Credentials) and hasattr(service_account.Credentials, "with_always_use_jwt_access"):
credentials = credentials.with_always_use_jwt_access(True)

# If no credentials are provided, then determine the appropriate
# defaults.
if credentials is None:
Expand All @@ -78,6 +126,24 @@ class {{ service.name }}Transport(metaclass=abc.ABCMeta):
# Lifted into its own function so it can be stubbed out during tests.
self._prep_wrapped_messages(client_info)


# TODO: Remove this function once google-auth >= 1.25.0 is required
@classmethod
def _get_scopes_kwargs(cls, host: str, scopes: Optional[Sequence[str]]) -> Dict[str, Optional[Sequence[str]]]:
"""Returns scopes kwargs to pass to google-auth methods depending on the google-auth version"""

scopes_kwargs = {}

if _GOOGLE_AUTH_VERSION and (
packaging.version.parse(_GOOGLE_AUTH_VERSION)
>= packaging.version.parse("1.25.0")
):
scopes_kwargs = {"scopes": scopes, "default_scopes": cls.AUTH_SCOPES}
else:
scopes_kwargs = {"scopes": scopes or cls.AUTH_SCOPES}

return scopes_kwargs

def _prep_wrapped_messages(self, client_info):
# Precomputed wrapped methods
self._wrapped_methods = {
Expand Down
Loading

0 comments on commit 4e687e7

Please sign in to comment.