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 Oct 14, 2021
1 parent 582fed9 commit 6c2276b
Show file tree
Hide file tree
Showing 9 changed files with 474 additions and 49 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,13 @@ OptionalRetry = Union[retries.Retry, object]
{% 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 @@ -42,8 +47,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 6c2276b

Please sign in to comment.