Skip to content

Commit

Permalink
refactor: cleanup and boost dependency reqs in generated clients (#1018)
Browse files Browse the repository at this point in the history
Boost Proto-Plus dependency to 1.19.4
Boost common protos dependency to 1.53.0
Boost Google API core requirement to 2.1.0 and (transitively) Google
Auth to 1.25.0

Remove logic for handling older auth library versions
  • Loading branch information
software-dov committed Oct 14, 2021
1 parent 062753f commit f170f6f
Show file tree
Hide file tree
Showing 35 changed files with 71 additions and 798 deletions.
4 changes: 2 additions & 2 deletions gapic/ads-templates/noxfile.py.j2
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import os
import nox # type: ignore


@nox.session(python=['3.7', '3.8'])
@nox.session(python=['3.7', '3.8', '3.9'])
def unit(session):
"""Run the unit test suite."""

Expand All @@ -25,7 +25,7 @@ def unit(session):
)


@nox.session(python=['3.7', '3.8'])
@nox.session(python=['3.7', '3.8', '3.9'])
def mypy(session):
"""Run the type checker."""
session.install('mypy')
Expand Down
12 changes: 9 additions & 3 deletions gapic/ads-templates/setup.py.j2
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,15 @@ setuptools.setup(
platforms='Posix; MacOS X; Windows',
include_package_data=True,
install_requires=(
'google-api-core >= 1.22.2, < 3.0.0dev',
'googleapis-common-protos >= 1.5.8',
{# TODO(dovs): remove when 1.x deprecation is complete #}
{% if 'rest' in opts.transport %}
'google-api-core[grpc] >= 2.1.0, < 3.0.0dev',
{% else %}
'google-api-core[grpc] >= 1.28.0, < 3.0.0dev',
{% endif %}
'googleapis-common-protos >= 1.53.0',
'grpcio >= 1.10.0',
'proto-plus >= 1.15.0',
'proto-plus >= 1.19.4',
{% if api.requires_package(('google', 'iam', 'v1')) %}
'grpc-google-iam-v1',
{% endif %}
Expand All @@ -38,6 +43,7 @@ setuptools.setup(
'Operating System :: OS Independent',
'Programming Language :: Python :: 3.7',
'Programming Language :: Python :: 3.8',
'Programming Language :: Python :: 3.9',
'Topic :: Internet',
'Topic :: Software Development :: Libraries :: Python Modules',
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

import abc
from typing import Awaitable, Callable, Dict, Optional, Sequence, Union
import packaging.version
import pkg_resources

import google.auth # type: ignore
Expand Down Expand Up @@ -38,15 +37,6 @@ 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(abc.ABC):
"""Abstract transport class for {{ service.name }}."""
Expand Down Expand Up @@ -99,7 +89,7 @@ class {{ service.name }}Transport(abc.ABC):
host += ':443'
self._host = host

scopes_kwargs = self._get_scopes_kwargs(self._host, scopes)
scopes_kwargs = {"scopes": scopes, "default_scopes": self.AUTH_SCOPES}

# Save the scopes.
self._scopes = scopes
Expand Down Expand Up @@ -127,28 +117,6 @@ class {{ service.name }}Transport(abc.ABC):
self._credentials = credentials


# TODO(busunkim): This method is in the base transport
# to avoid duplicating code across the transport classes. These functions
# should be deleted once the minimum required versions of google-auth is increased.

# 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):
# Precompute the wrapped methods.
self._wrapped_methods = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ from google.api_core import operations_v1 # type: ignore
{% endif %}
from google.auth import credentials as ga_credentials # type: ignore
from google.auth.transport.grpc import SslCredentials # type: ignore
import packaging.version

import grpc # type: ignore
from grpc.experimental import aio # type: ignore
Expand Down
6 changes: 3 additions & 3 deletions gapic/templates/noxfile.py.j2
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ def unit(session):
)


@nox.session(python='3.7')
@nox.session(python='3.9')
def cover(session):
"""Run the final coverage report.
This outputs the coverage report aggregating coverage from the unit
Expand All @@ -56,7 +56,7 @@ def cover(session):
session.run("coverage", "erase")


@nox.session(python=['3.6', '3.7'])
@nox.session(python=['3.6', '3.7', '3.8', '3.9'])
def mypy(session):
"""Run the type checker."""
session.install('mypy', 'types-pkg_resources')
Expand Down Expand Up @@ -103,7 +103,7 @@ def check_lower_bounds(session):
str(LOWER_BOUND_CONSTRAINTS_FILE),
)

@nox.session(python='3.6')
@nox.session(python='3.9')
def docs(session):
"""Build the docs for this library."""

Expand Down
15 changes: 9 additions & 6 deletions gapic/templates/setup.py.j2
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,17 @@ setuptools.setup(
platforms='Posix; MacOS X; Windows',
include_package_data=True,
install_requires=(
'google-api-core[grpc] >= 1.27.0, < 3.0.0dev',
{# TODO(dovs): remove when 1.x deprecation is complete #}
{% if 'rest' in opts.transport %}
'google-api-core[grpc] >= 2.1.0, < 3.0.0dev',
{% else %}
'google-api-core[grpc] >= 1.28.0, < 3.0.0dev',
{% endif %}
'libcst >= 0.2.5',
'proto-plus >= 1.15.0',
'packaging >= 14.3',
{%- if api.requires_package(('google', 'iam', 'v1')) or opts.add_iam_methods %}
'proto-plus >= 1.19.4',
{% if api.requires_package(('google', 'iam', 'v1')) or opts.add_iam_methods %}
'grpc-google-iam-v1 >= 0.12.3, < 0.13dev',
{%- endif %}
{% endif %}
),
python_requires='>=3.6',
classifiers=[
Expand All @@ -44,7 +48,6 @@ setuptools.setup(
'Programming Language :: Python :: 3.7',
'Programming Language :: Python :: 3.8',
'Programming Language :: Python :: 3.9',
'Programming Language :: Python :: 3.10',
'Topic :: Internet',
'Topic :: Software Development :: Libraries :: Python Modules',
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

import os
import mock
import packaging.version

import grpc
from grpc.experimental import aio
Expand All @@ -28,7 +27,7 @@ from {{ (api.naming.module_namespace + (api.naming.versioned_module_name,) + ser
from {{ (api.naming.module_namespace + (api.naming.versioned_module_name,) + service.meta.address.subpackage)|join(".") }}.services.{{ service.name|snake_case }} import {{ service.async_client_name }}
{% endif %}
from {{ (api.naming.module_namespace + (api.naming.versioned_module_name,) + service.meta.address.subpackage)|join(".") }}.services.{{ service.name|snake_case }} import transports
from {{ (api.naming.module_namespace + (api.naming.versioned_module_name,) + service.meta.address.subpackage)|join(".") }}.services.{{ service.name|snake_case }}.transports.base import _GOOGLE_AUTH_VERSION

from google.api_core import client_options
from google.api_core import exceptions as core_exceptions
from google.api_core import grpc_helpers
Expand All @@ -55,19 +54,6 @@ from google.iam.v1 import policy_pb2 # type: ignore
{% endfilter %}


# TODO(busunkim): Once google-auth >= 1.25.0 is required transitively
# through google-api-core:
# - Delete the auth "less than" test cases
# - Delete these pytest markers (Make the "greater than or equal to" tests the default).
requires_google_auth_lt_1_25_0 = pytest.mark.skipif(
packaging.version.parse(_GOOGLE_AUTH_VERSION) >= packaging.version.parse("1.25.0"),
reason="This test requires google-auth < 1.25.0",
)
requires_google_auth_gte_1_25_0 = pytest.mark.skipif(
packaging.version.parse(_GOOGLE_AUTH_VERSION) < packaging.version.parse("1.25.0"),
reason="This test requires google-auth >= 1.25.0",
)

def client_cert_source_callback():
return b"cert bytes", b"key bytes"

Expand Down Expand Up @@ -1527,7 +1513,6 @@ def test_{{ service.name|snake_case }}_base_transport():
{% endif %}


@requires_google_auth_gte_1_25_0
def test_{{ service.name|snake_case }}_base_transport_with_credentials_file():
# Instantiate the base transport with a credentials file
with mock.patch.object(google.auth, 'load_credentials_from_file', autospec=True) as load_creds, mock.patch('{{ (api.naming.module_namespace + (api.naming.versioned_module_name,) + service.meta.address.subpackage)|join(".") }}.services.{{ service.name|snake_case }}.transports.{{ service.name }}Transport._prep_wrapped_messages') as Transport:
Expand All @@ -1547,25 +1532,6 @@ def test_{{ service.name|snake_case }}_base_transport_with_credentials_file():
)


@requires_google_auth_lt_1_25_0
def test_{{ service.name|snake_case }}_base_transport_with_credentials_file_old_google_auth():
# Instantiate the base transport with a credentials file
with mock.patch.object(google.auth, 'load_credentials_from_file', autospec=True) as load_creds, mock.patch('{{ (api.naming.module_namespace + (api.naming.versioned_module_name,) + service.meta.address.subpackage)|join(".") }}.services.{{ service.name|snake_case }}.transports.{{ service.name }}Transport._prep_wrapped_messages') as Transport:
Transport.return_value = None
load_creds.return_value = (ga_credentials.AnonymousCredentials(), None)
transport = transports.{{ service.name }}Transport(
credentials_file="credentials.json",
quota_project_id="octopus",
)
load_creds.assert_called_once_with("credentials.json", scopes=(
{% for scope in service.oauth_scopes %}
'{{ scope }}',
{% endfor %}
),
quota_project_id="octopus",
)


def test_{{ service.name|snake_case }}_base_transport_with_adc():
# Test the default credentials are used if credentials and credentials_file are None.
with mock.patch.object(google.auth, 'default', autospec=True) as adc, mock.patch('{{ (api.naming.module_namespace + (api.naming.versioned_module_name,) + service.meta.address.subpackage)|join(".") }}.services.{{ service.name|snake_case }}.transports.{{ service.name }}Transport._prep_wrapped_messages') as Transport:
Expand All @@ -1575,7 +1541,6 @@ def test_{{ service.name|snake_case }}_base_transport_with_adc():
adc.assert_called_once()


@requires_google_auth_gte_1_25_0
def test_{{ service.name|snake_case }}_auth_adc():
# If no credentials are provided, we should use ADC credentials.
with mock.patch.object(google.auth, 'default', autospec=True) as adc:
Expand All @@ -1591,21 +1556,6 @@ def test_{{ service.name|snake_case }}_auth_adc():
)


@requires_google_auth_lt_1_25_0
def test_{{ service.name|snake_case }}_auth_adc_old_google_auth():
# If no credentials are provided, we should use ADC credentials.
with mock.patch.object(google.auth, 'default', autospec=True) as adc:
adc.return_value = (ga_credentials.AnonymousCredentials(), None)
{{ service.client_name }}()
adc.assert_called_once_with(
scopes=(
{%- for scope in service.oauth_scopes %}
'{{ scope }}',
{%- endfor %}),
quota_project_id=None,
)


{% if 'grpc' in opts.transport %}
@pytest.mark.parametrize(
"transport_class",
Expand All @@ -1614,7 +1564,6 @@ def test_{{ service.name|snake_case }}_auth_adc_old_google_auth():
transports.{{ service.name }}GrpcAsyncIOTransport,
],
)
@requires_google_auth_gte_1_25_0
def test_{{ service.name|snake_case }}_transport_auth_adc(transport_class):
# If credentials and host are not provided, the transport class should use
# ADC credentials.
Expand All @@ -1631,26 +1580,6 @@ def test_{{ service.name|snake_case }}_transport_auth_adc(transport_class):
)


@pytest.mark.parametrize(
"transport_class",
[
transports.{{ service.name }}GrpcTransport,
transports.{{ service.name }}GrpcAsyncIOTransport,
],
)
@requires_google_auth_lt_1_25_0
def test_{{ service.name|snake_case }}_transport_auth_adc_old_google_auth(transport_class):
# If credentials and host are not provided, the transport class should use
# ADC credentials.
with mock.patch.object(google.auth, "default", autospec=True) as adc:
adc.return_value = (ga_credentials.AnonymousCredentials(), None)
transport_class(quota_project_id="octopus")
adc.assert_called_once_with(scopes=(
{% for scope in service.oauth_scopes %}
'{{ scope }}',
{% endfor %}),
quota_project_id="octopus",
)


@pytest.mark.parametrize(
Expand Down

0 comments on commit f170f6f

Please sign in to comment.