Skip to content

Commit 009fc71

Browse files
committed
add showcase tests; clean up code
1 parent 4e3138c commit 009fc71

File tree

57 files changed

+377
-205
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

57 files changed

+377
-205
lines changed

gapic/ads-templates/%namespace/%name/%version/%sub/services/%service/client.py.j2

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,11 @@ from google.auth.transport.grpc import SslCredentials # type: ignore
2323
from google.auth.exceptions import MutualTLSChannelError # type: ignore
2424
from google.oauth2 import service_account # type: ignore
2525

26+
try:
27+
from google.api_core import version_header
28+
except ImportError:
29+
version_header = None
30+
2631
{% set package_path = api.naming.module_namespace|join('.') + "." + api.naming.versioned_module_name %}
2732
from {{package_path}} import gapic_version as package_version
2833

@@ -479,11 +484,21 @@ class {{ service.client_name }}(metaclass={{ service.client_name }}Meta):
479484
)
480485
{% endif %}
481486

482-
{% if service.version %}
483-
metadata = tuple(metadata) + (
484-
gapic_v1.version_header.to_grpc_metadata("{{ service.version }}"),
485-
)
486-
{% endif %}
487+
{#
488+
Add API Version to metadata as per https://github.com/aip-dev/google.aip.dev/pull/1331.
489+
When using this macro, ensure the calling template
490+
generates the following lines:
491+
try:
492+
from google.api_core import version_header
493+
except ImportError:
494+
version_header = None
495+
#}
496+
{% if service.version %}
497+
if version_header:
498+
metadata = tuple(metadata) + (
499+
version_header.to_api_version_header("{{ service.version }}"),
500+
)
501+
{% endif %}{# service.version #}
487502
{#
488503
Automatically populate UUID4 fields according to
489504
https://google.aip.dev/client-libraries/4235 when the

gapic/ads-templates/setup.py.j2

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,7 @@ else:
2929
release_status = "Development Status :: 5 - Production/Stable"
3030

3131
dependencies = [
32-
"google-api-core[grpc] @ git+https://github.com/googleapis/python-api-core.git@add-api-version-header",
33-
#"google-api-core[grpc] >= 2.10.0, < 3.0.0dev",
32+
"google-api-core[grpc] >= 2.10.0, < 3.0.0dev",
3433
"google-auth >= 2.14.1, <3.0.0dev",
3534
"googleapis-common-protos >= 1.53.0",
3635
"grpcio >= 1.10.0",

gapic/ads-templates/tests/unit/gapic/%name_%version/%sub/test_%service.py.j2

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ from google.oauth2 import service_account
3939
from {{ (api.naming.module_namespace + (api.naming.versioned_module_name,) + service.meta.address.subpackage)|join(".") }}.services.{{ service.name|snake_case }} import {{ service.client_name }}
4040
from {{ (api.naming.module_namespace + (api.naming.versioned_module_name,) + service.meta.address.subpackage)|join(".") }}.services.{{ service.name|snake_case }} import transports
4141

42+
from google.api_core import api_core_version
4243
from google.api_core import client_options
4344
from google.api_core import exceptions as core_exceptions
4445
from google.api_core import grpc_helpers
@@ -69,6 +70,11 @@ from google.iam.v1 import options_pb2 # type: ignore
6970
from google.iam.v1 import policy_pb2 # type: ignore
7071
{% endif %}
7172
{% endfilter %}
73+
try:
74+
from google.api_core import version_header
75+
except ImportError:
76+
version_header = None
77+
7278

7379
{% with uuid4_re = "[a-f0-9]{8}-?[a-f0-9]{4}-?4[a-f0-9]{3}-?[89ab][a-f0-9]{3}-?[a-f0-9]{12}" %}
7480

@@ -147,6 +153,7 @@ def test_{{ service.client_name|snake_case }}_service_account_always_use_jwt(tra
147153
use_jwt.assert_not_called()
148154

149155

156+
150157
@pytest.mark.parametrize("client_class,transport_name", [
151158
{% if 'grpc' in opts.transport %}
152159
({{ service.client_name }}, "grpc"),
@@ -636,6 +643,35 @@ def test_{{ method_name }}(request_type, transport: str = 'grpc'):
636643
{% endwith %}{# auto_populated_field_sample_value #}
637644

638645

646+
{% if service.version %}
647+
@pytest.mark.parametrize("transport_name", [
648+
{% if 'grpc' in opts.transport %}
649+
("grpc"),
650+
{% endif %}
651+
{% if 'rest' in opts.transport %}
652+
("rest"),
653+
{% endif %}
654+
])
655+
def test_{{ method_name }}_api_version_header(transport_name):
656+
# TODO: Make this test unconditional once the minimum supported version of
657+
# google-api-core becomes 2.19.0 or higher.
658+
api_core_major, api_core_minor = [int(part) for part in api_core_version.__version__.split(".")[0:2]]
659+
if api_core_major > 2 or (api_core_major == 2 and api_core_minor >= 19):
660+
client = {{ service.client_name }}(credentials=ga_credentials.AnonymousCredentials(), transport=transport_name)
661+
# Mock the actual call within the gRPC stub, and fake the request.
662+
with mock.patch.object(
663+
type(client.transport.{{ method.transport_safe_name|snake_case }}),
664+
'__call__'
665+
) as call:
666+
client.{{ method_name }}()
667+
668+
# Establish that the api version header was sent.
669+
_, _, kw = call.mock_calls[0]
670+
assert kw['metadata'][0] == (version_header.API_VERSION_METADATA_KEY, "{{ service.version }}")
671+
else:
672+
pytest.skip("google-api-core>=2.19.0 is required for `google.api_core.version_header`")
673+
{% endif %}{# service.version #}
674+
639675
{% if not method.client_streaming %}
640676
def test_{{ method_name }}_empty_call():
641677
# This test is a coverage failsafe to make sure that totally empty calls,
@@ -904,9 +940,9 @@ def test_{{ method_name }}_pager(transport_name: str = "grpc"):
904940
RuntimeError,
905941
)
906942

907-
metadata = ()
943+
expected_metadata = ()
908944
{% if method.field_headers %}
909-
metadata = tuple(metadata) + (
945+
expected_metadata = tuple(expected_metadata) + (
910946
gapic_v1.routing_header.to_grpc_metadata((
911947
{% for field_header in method.field_headers %}
912948
{% if not method.client_streaming %}
@@ -918,7 +954,13 @@ def test_{{ method_name }}_pager(transport_name: str = "grpc"):
918954
{% endif %}
919955
pager = client.{{ method_name }}(request={})
920956

921-
assert pager._metadata == metadata
957+
{% if service.version %}
958+
if version_header:
959+
expected_metadata = tuple(expected_metadata) + (
960+
version_header.to_api_version_header("{{ service.version }}"),
961+
)
962+
{% endif %}
963+
assert pager._metadata == expected_metadata
922964

923965
results = list(pager)
924966
assert len(results) == 6

gapic/templates/%namespace/%name_%version/%sub/services/%service/_client_macros.j2

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -183,12 +183,7 @@
183183
)
184184
{% endif %} {# method.explicit_routing #}
185185

186-
{% if service.version %}
187-
metadata = tuple(metadata) + (
188-
gapic_v1.version_header.to_grpc_metadata("{{ service.version }}"),
189-
)
190-
{% endif %}
191-
186+
{{ add_api_version_header_to_metadata(service) }}
192187
{{ auto_populate_uuid4_fields(api, method) }}
193188

194189
# Validate the universe domain.
@@ -297,3 +292,21 @@
297292
{% endif %}{# if method_settings is not none #}
298293
{% endwith %}{# method_settings #}
299294
{% endmacro %}
295+
296+
{% macro add_api_version_header_to_metadata(service) %}
297+
{#
298+
Add API Version to metadata as per https://github.com/aip-dev/google.aip.dev/pull/1331.
299+
When using this macro, ensure the calling template
300+
generates the following lines:
301+
try:
302+
from google.api_core import version_header
303+
except ImportError:
304+
version_header = None
305+
#}
306+
{% if service.version %}
307+
if version_header:
308+
metadata = tuple(metadata) + (
309+
version_header.to_api_version_header("{{ service.version }}"),
310+
)
311+
{% endif %}{# service.version #}
312+
{% endmacro %}

gapic/templates/%namespace/%name_%version/%sub/services/%service/async_client.py.j2

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,11 @@ from google.api_core import retry_async as retries
2424
from google.auth import credentials as ga_credentials # type: ignore
2525
from google.oauth2 import service_account # type: ignore
2626

27+
try:
28+
from google.api_core import version_header
29+
except ImportError:
30+
version_header = None
31+
2732
try:
2833
OptionalRetry = Union[retries.AsyncRetry, gapic_v1.method._MethodDefault, None]
2934
except AttributeError: # pragma: NO COVER
@@ -391,12 +396,7 @@ class {{ service.async_client_name }}:
391396
)
392397
{% endif %}
393398

394-
{% if service.version %}
395-
metadata = tuple(metadata) + (
396-
gapic_v1.version_header.to_grpc_metadata("{{ service.version }}")
397-
)
398-
{% endif %}
399-
399+
{{ macros.add_api_version_header_to_metadata(service) }}
400400
{{ macros.auto_populate_uuid4_fields(api, method) }}
401401

402402
# Validate the universe domain.

gapic/templates/%namespace/%name_%version/%sub/services/%service/client.py.j2

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,11 @@ from google.auth.transport.grpc import SslCredentials # type: ignore
3131
from google.auth.exceptions import MutualTLSChannelError # type: ignore
3232
from google.oauth2 import service_account # type: ignore
3333

34+
try:
35+
from google.api_core import version_header
36+
except ImportError:
37+
version_header = None
38+
3439
try:
3540
OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None]
3641
except AttributeError: # pragma: NO COVER

gapic/templates/setup.py.j2

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,7 @@ else:
3030
release_status = "Development Status :: 5 - Production/Stable"
3131

3232
dependencies = [
33-
"google-api-core[grpc] @ git+https://github.com/googleapis/python-api-core.git@add-api-version-header",
34-
#"google-api-core[grpc] >= 1.34.1, <3.0.0dev,!=2.0.*,!=2.1.*,!=2.2.*,!=2.3.*,!=2.4.*,!=2.5.*,!=2.6.*,!=2.7.*,!=2.8.*,!=2.9.*,!=2.10.*",
33+
"google-api-core[grpc] >= 1.34.1, <3.0.0dev,!=2.0.*,!=2.1.*,!=2.2.*,!=2.3.*,!=2.4.*,!=2.5.*,!=2.6.*,!=2.7.*,!=2.8.*,!=2.9.*,!=2.10.*",
3534
# Exclude incompatible versions of `google-auth`
3635
# See https://github.com/googleapis/google-cloud-python/issues/12364
3736
"google-auth >= 2.14.1, <3.0.0dev,!=2.24.0,!=2.25.0",

gapic/templates/testing/_default_constraints.j2

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
# List all library dependencies and extras in this file.
44
proto-plus
55
protobuf
6+
google-api-core
67
{% for package_tuple, package_info in pypi_packages.items() %}
78
{# Quick check to make sure the package is different from this setup.py #}
89
{% if api.naming.warehouse_package_name != package_info.package_name %}

gapic/templates/tests/unit/gapic/%name_%version/%sub/test_%service.py.j2

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,10 @@ from google.iam.v1 import options_pb2 # type: ignore
7777
from google.iam.v1 import policy_pb2 # type: ignore
7878
{% endif %}
7979
{% endfilter %}
80+
try:
81+
from google.api_core import version_header
82+
except ImportError:
83+
version_header = None
8084

8185

8286
def client_cert_source_callback():
@@ -178,6 +182,49 @@ def test__get_api_endpoint():
178182
{{ service.client_name }}._get_api_endpoint(None, mock_client_cert_source, mock_universe, "auto")
179183
assert str(excinfo.value) == "mTLS is not supported in any universe other than googleapis.com."
180184

185+
{% if service.version %}
186+
{% for method in service.methods.values() %}{% with method_name = method.name|snake_case %}
187+
{% for mode in ["", "async"] %}
188+
{% if mode == "async" %}
189+
async def test_{{ method_name }}_api_version_header_async(transport_name="grpc"):
190+
client = {{ service.async_client_name }}(credentials=ga_credentials.AnonymousCredentials(), transport=transport_name)
191+
{% else %}
192+
@pytest.mark.parametrize("transport_name", [
193+
{% if 'grpc' in opts.transport %}
194+
("grpc"),
195+
{% endif %}
196+
{% if 'rest' in opts.transport %}
197+
("rest"),
198+
{% endif %}
199+
])
200+
def test_{{ method_name }}_api_version_header(transport_name):
201+
client = {{ service.client_name }}(credentials=ga_credentials.AnonymousCredentials(), transport=transport_name)
202+
{% endif %}
203+
# TODO: Make this test unconditional once the minimum supported version of
204+
# google-api-core becomes 2.19.0 or higher.
205+
api_core_major, api_core_minor = [int(part) for part in api_core_version.__version__.split(".")[0:2]]
206+
if api_core_major > 2 or (api_core_major == 2 and api_core_minor >= 19):
207+
# Mock the actual call within the gRPC stub, and fake the request.
208+
with mock.patch.object(
209+
type(client.transport.{{ method.transport_safe_name|snake_case }}),
210+
'__call__'
211+
) as call:
212+
{% if mode == "async" %}
213+
await client.{{ method_name }}()
214+
{% else %}
215+
client.{{ method_name }}()
216+
{% endif %}
217+
218+
# Establish that the api version header was sent.
219+
_, _, kw = call.mock_calls[0]
220+
assert kw['metadata'][0] == (gapic_v1.version_header.API_VERSION_METADATA_KEY, "{{ service.version }}")
221+
else:
222+
pytest.skip("google-api-core>=2.19.0 is required for `google.api_core.version_header`")
223+
{% endfor %}{# mode #}
224+
{% endwith %}
225+
{% endfor %}
226+
{% endif %}{# service.version #}
227+
181228
def test__get_universe_domain():
182229
client_universe_domain = "foo.com"
183230
universe_domain_env = "bar.com"

gapic/templates/tests/unit/gapic/%name_%version/%sub/test_macros.j2

Lines changed: 9 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -121,32 +121,6 @@ def test_{{ method_name }}(request_type, transport: str = 'grpc'):
121121
{% endif %}
122122
{% endwith %}{# auto_populated_field_sample_value #}
123123

124-
{% if service.version %}
125-
{% for mode in ["", "async"] %}
126-
{% if mode == "async" %}
127-
async def test_{{ method_name }}_api_version_header_async():
128-
client = {{ service.async_client_name }}(credentials=ga_credentials.AnonymousCredentials())
129-
{% else %}
130-
def test_{{ method_name }}_api_version_header():
131-
client = {{ service.client_name }}(credentials=ga_credentials.AnonymousCredentials())
132-
{% endif %}
133-
# Mock the actual call within the gRPC stub, and fake the request.
134-
with mock.patch.object(
135-
type(client.transport.{{ method.transport_safe_name|snake_case }}),
136-
'__call__'
137-
) as call:
138-
{% if mode == "async" %}
139-
await client.{{ method_name }}()
140-
{% else %}
141-
client.{{ method_name }}()
142-
{% endif %}
143-
144-
# Establish that the api version header was sent.
145-
_, _, kw = call.mock_calls[0]
146-
assert kw['metadata'][0] == (gapic_v1.version_header.API_VERSION_METADATA_KEY, "{{ service.version }}")
147-
{% endfor %}{# mode #}
148-
{% endif %}{# service.version #}
149-
150124
{% if not method.client_streaming %}
151125
def test_{{ method_name }}_empty_call():
152126
# This test is a coverage failsafe to make sure that totally empty calls,
@@ -776,9 +750,9 @@ def test_{{ method_name }}_pager(transport_name: str = "grpc"):
776750
RuntimeError,
777751
)
778752

779-
metadata = ()
753+
expected_metadata = ()
780754
{% if not method.explicit_routing and method.field_headers %}
781-
metadata = tuple(metadata) + (
755+
expected_metadata = tuple(expected_metadata) + (
782756
gapic_v1.routing_header.to_grpc_metadata((
783757
{% for field_header in method.field_headers %}
784758
{% if not method.client_streaming %}
@@ -788,9 +762,15 @@ def test_{{ method_name }}_pager(transport_name: str = "grpc"):
788762
)),
789763
)
790764
{% endif %}
765+
{% if service.version %}
766+
if version_header:
767+
expected_metadata = tuple(expected_metadata) + (
768+
version_header.to_api_version_header("{{ service.version }}"),
769+
)
770+
{% endif %}
791771
pager = client.{{ method_name }}(request={})
792772

793-
assert pager._metadata == metadata
773+
assert pager._metadata == expected_metadata
794774

795775
results = list(pager)
796776
assert len(results) == 6

noxfile.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ def showcase_library(
189189
session.log("-" * 70)
190190

191191
# Install gapic-generator-python
192-
session.install("-e", ".")
192+
session.install("-e", ".", "--no-cache-dir")
193193

194194
# Install grpcio-tools for protoc
195195
session.install("grpcio-tools")
@@ -266,12 +266,12 @@ def showcase_library(
266266
f"{tmp_dir}/testing/constraints-{session.python}.txt"
267267
)
268268
# Install the library with a constraints file.
269-
session.install("-e", tmp_dir, "-r", constraints_path)
269+
session.install("-e", tmp_dir, "-r", constraints_path, "--no-cache-dir")
270270
else:
271271
# The ads templates do not have constraints files.
272272
# See https://github.com/googleapis/gapic-generator-python/issues/1788
273273
# Install the library without a constraints file.
274-
session.install("-e", tmp_dir)
274+
session.install("-e", tmp_dir, "--no-cache-dir")
275275
yield tmp_dir
276276

277277

setup.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,7 @@
2828
# Ensure that the lower bounds of these dependencies match what we have in the
2929
# templated setup.py.j2: https://github.com/googleapis/gapic-generator-python/blob/main/gapic/templates/setup.py.j2
3030
"click >= 6.7",
31-
"google-api-core @ git+https://github.com/googleapis/python-api-core.git@add-api-version-header",
32-
#"google-api-core[grpc] >= 1.34.1, <3.0.0dev,!=2.0.*,!=2.1.*,!=2.2.*,!=2.3.*,!=2.4.*,!=2.5.*,!=2.6.*,!=2.7.*,!=2.8.*,!=2.9.*,!=2.10.*",
31+
"google-api-core[grpc] >= 1.34.1, <3.0.0dev,!=2.0.*,!=2.1.*,!=2.2.*,!=2.3.*,!=2.4.*,!=2.5.*,!=2.6.*,!=2.7.*,!=2.8.*,!=2.9.*,!=2.10.*",
3332
"googleapis-common-protos >= 1.55.0",
3433
"grpcio >= 1.24.3",
3534
# 2.11.0 is required which adds the `default` argument to `jinja-filters.map()`

0 commit comments

Comments
 (0)