Skip to content

Commit e263737

Browse files
authored
fix: retry and timeout values do not propagate in requests during pagination (#2065)
1 parent d2ce174 commit e263737

File tree

40 files changed

+665
-83
lines changed

40 files changed

+665
-83
lines changed

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -509,6 +509,8 @@ class {{ service.client_name }}(metaclass={{ service.client_name }}Meta):
509509
method=rpc,
510510
request=request,
511511
response=response,
512+
retry=retry,
513+
timeout=timeout,
512514
metadata=metadata,
513515
)
514516
{% endif %}

packages/gapic-generator/gapic/ads-templates/%namespace/%name/%version/%sub/services/%service/pagers.py.j2

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,13 @@
77
{# This lives within the loop in order to ensure that this template
88
is empty if there are no paged methods.
99
-#}
10-
from typing import Any, Callable, Iterable, Sequence, Tuple, Optional, Iterator
10+
from google.api_core import gapic_v1
11+
from google.api_core import retry as retries
12+
from typing import Any, Callable, Iterable, Sequence, Tuple, Optional, Iterator, Union
13+
try:
14+
OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None]
15+
except AttributeError: # pragma: NO COVER
16+
OptionalRetry = Union[retries.Retry, object, None] # type: ignore
1117

1218
{% filter sort_lines %}
1319
{% for method in service.methods.values() | selectattr('paged_result_field') %}
@@ -41,6 +47,8 @@ class {{ method.name }}Pager:
4147
method: Callable[..., {{ method.output.ident }}],
4248
request: {{ method.input.ident }},
4349
response: {{ method.output.ident }},
50+
retry: OptionalRetry = gapic_v1.method.DEFAULT,
51+
timeout: Union[float, object] = gapic_v1.method.DEFAULT,
4452
metadata: Sequence[Tuple[str, str]] = ()):
4553
"""Instantiate the pager.
4654

@@ -51,12 +59,17 @@ class {{ method.name }}Pager:
5159
The initial request object.
5260
response (:class:`{{ method.output.ident.sphinx }}`):
5361
The initial response object.
62+
retry (google.api_core.retry.Retry): Designation of what errors,
63+
if any, should be retried.
64+
timeout (float): The timeout for this request.
5465
metadata (Sequence[Tuple[str, str]]): Strings which should be
5566
sent along with the request as metadata.
5667
"""
5768
self._method = method
5869
self._request = {{ method.input.ident }}(request)
5970
self._response = response
71+
self._retry = retry
72+
self._timeout = timeout
6073
self._metadata = metadata
6174

6275
def __getattr__(self, name: str) -> Any:
@@ -67,7 +80,7 @@ class {{ method.name }}Pager:
6780
yield self._response
6881
while self._response.next_page_token:
6982
self._request.page_token = self._response.next_page_token
70-
self._response = self._method(self._request, metadata=self._metadata)
83+
self._response = self._method(self._request, retry=self._retry, timeout=self._timeout, metadata=self._metadata)
7184
yield self._response
7285

7386
{% if method.paged_result_field.map %}

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

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ from google.api_core import client_options
4545
from google.api_core import exceptions as core_exceptions
4646
from google.api_core import grpc_helpers
4747
from google.api_core import path_template
48+
from google.api_core import retry as retries
4849
{% if service.has_lro %}
4950
from google.api_core import future
5051
from google.api_core import operation
@@ -938,6 +939,8 @@ def test_{{ method_name }}_pager(transport_name: str = "grpc"):
938939
)
939940

940941
expected_metadata = ()
942+
retry = retries.Retry()
943+
timeout = 5
941944
{% if method.field_headers %}
942945
expected_metadata = tuple(expected_metadata) + (
943946
gapic_v1.routing_header.to_grpc_metadata((
@@ -949,7 +952,7 @@ def test_{{ method_name }}_pager(transport_name: str = "grpc"):
949952
)),
950953
)
951954
{% endif %}
952-
pager = client.{{ method_name }}(request={})
955+
pager = client.{{ method_name }}(request={}, retry=retry, timeout=timeout)
953956

954957
{% if service.version %}
955958
if HAS_GOOGLE_API_CORE_VERSION_HEADER:
@@ -958,6 +961,8 @@ def test_{{ method_name }}_pager(transport_name: str = "grpc"):
958961
)
959962
{% endif %}
960963
assert pager._metadata == expected_metadata
964+
assert pager._retry == retry
965+
assert pager._timeout == timeout
961966

962967
results = list(pager)
963968
assert len(results) == 6

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,8 @@
217217
method=rpc,
218218
request=request,
219219
response=response,
220+
retry=retry,
221+
timeout=timeout,
220222
metadata=metadata,
221223
)
222224
{% elif method.extended_lro and full_extended_lro %}

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -414,6 +414,8 @@ class {{ service.async_client_name }}:
414414
method=rpc,
415415
request=request,
416416
response=response,
417+
retry=retry,
418+
timeout=timeout,
417419
metadata=metadata,
418420
)
419421
{% endif %}

packages/gapic-generator/gapic/templates/%namespace/%name_%version/%sub/services/%service/pagers.py.j2

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,15 @@
77
{# This lives within the loop in order to ensure that this template
88
is empty if there are no paged methods.
99
#}
10-
from typing import Any, AsyncIterator, Awaitable, Callable, Sequence, Tuple, Optional, Iterator
10+
from google.api_core import gapic_v1
11+
from google.api_core import retry as retries
12+
from typing import Any, AsyncIterator, Awaitable, Callable, Sequence, Tuple, Optional, Iterator, Union
13+
try:
14+
OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault, None]
15+
OptionalAsyncRetry = Union[retries.AsyncRetry, gapic_v1.method._MethodDefault, None]
16+
except AttributeError: # pragma: NO COVER
17+
OptionalRetry = Union[retries.Retry, object, None] # type: ignore
18+
OptionalAsyncRetry = Union[retries.AsyncRetry, object, None] # type: ignore
1119

1220
{% filter sort_lines %}
1321
{% for method in service.methods.values() | selectattr('paged_result_field') %}
@@ -43,6 +51,8 @@ class {{ method.name }}Pager:
4351
request: {{ method.input.ident }},
4452
response: {{ method.output.ident }},
4553
*,
54+
retry: OptionalRetry = gapic_v1.method.DEFAULT,
55+
timeout: Union[float, object] = gapic_v1.method.DEFAULT,
4656
metadata: Sequence[Tuple[str, str]] = ()):
4757
"""Instantiate the pager.
4858

@@ -53,12 +63,17 @@ class {{ method.name }}Pager:
5363
The initial request object.
5464
response ({{ method.output.ident.sphinx }}):
5565
The initial response object.
66+
retry (google.api_core.retry.Retry): Designation of what errors,
67+
if any, should be retried.
68+
timeout (float): The timeout for this request.
5669
metadata (Sequence[Tuple[str, str]]): Strings which should be
5770
sent along with the request as metadata.
5871
"""
5972
self._method = method
6073
self._request = {{ method.input.ident }}(request)
6174
self._response = response
75+
self._retry = retry
76+
self._timeout = timeout
6277
self._metadata = metadata
6378

6479
def __getattr__(self, name: str) -> Any:
@@ -69,7 +84,7 @@ class {{ method.name }}Pager:
6984
yield self._response
7085
while self._response.next_page_token:
7186
self._request.page_token = self._response.next_page_token
72-
self._response = self._method(self._request, metadata=self._metadata)
87+
self._response = self._method(self._request, retry=self._retry, timeout=self._timeout, metadata=self._metadata)
7388
yield self._response
7489

7590
{% if method.paged_result_field.map %}
@@ -113,6 +128,8 @@ class {{ method.name }}AsyncPager:
113128
request: {{ method.input.ident }},
114129
response: {{ method.output.ident }},
115130
*,
131+
retry: OptionalAsyncRetry = gapic_v1.method.DEFAULT,
132+
timeout: Union[float, object] = gapic_v1.method.DEFAULT,
116133
metadata: Sequence[Tuple[str, str]] = ()):
117134
"""Instantiates the pager.
118135

@@ -123,12 +140,17 @@ class {{ method.name }}AsyncPager:
123140
The initial request object.
124141
response ({{ method.output.ident.sphinx }}):
125142
The initial response object.
143+
retry (google.api_core.retry.AsyncRetry): Designation of what errors,
144+
if any, should be retried.
145+
timeout (float): The timeout for this request.
126146
metadata (Sequence[Tuple[str, str]]): Strings which should be
127147
sent along with the request as metadata.
128148
"""
129149
self._method = method
130150
self._request = {{ method.input.ident }}(request)
131151
self._response = response
152+
self._retry = retry
153+
self._timeout = timeout
132154
self._metadata = metadata
133155

134156
def __getattr__(self, name: str) -> Any:
@@ -139,7 +161,7 @@ class {{ method.name }}AsyncPager:
139161
yield self._response
140162
while self._response.next_page_token:
141163
self._request.page_token = self._response.next_page_token
142-
self._response = await self._method(self._request, metadata=self._metadata)
164+
self._response = await self._method(self._request, retry=self._retry, timeout=self._timeout, metadata=self._metadata)
143165
yield self._response
144166
{% if method.paged_result_field.map %}
145167
def __aiter__(self) -> Iterator[Tuple[str, {{ method.paged_result_field.type.fields.get('value').ident }}]]:

packages/gapic-generator/gapic/templates/noxfile.py.j2

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,9 @@ def cover(session):
176176
def mypy(session):
177177
"""Run the type checker."""
178178
session.install(
179-
'mypy',
179+
# TODO(https://github.com/googleapis/gapic-generator-python/issues/2066):
180+
# Ignore release of mypy 1.11.0 which may have a regression
181+
'mypy!=1.11.0',
180182
'types-requests',
181183
'types-protobuf'
182184
)

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ from google.api_core import exceptions as core_exceptions
5151
from google.api_core import grpc_helpers
5252
from google.api_core import grpc_helpers_async
5353
from google.api_core import path_template
54+
from google.api_core import retry as retries
5455
{% if service.has_lro or service.has_extended_lro %}
5556
from google.api_core import future
5657
{% endif %}

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -850,6 +850,8 @@ def test_{{ method_name }}_pager(transport_name: str = "grpc"):
850850
)
851851

852852
expected_metadata = ()
853+
retry = retries.Retry()
854+
timeout = 5
853855
{% if not method.explicit_routing and method.field_headers %}
854856
expected_metadata = tuple(expected_metadata) + (
855857
gapic_v1.routing_header.to_grpc_metadata((
@@ -867,9 +869,11 @@ def test_{{ method_name }}_pager(transport_name: str = "grpc"):
867869
version_header.to_api_version_header("{{ service.version }}"),
868870
)
869871
{% endif %}
870-
pager = client.{{ method_name }}(request={})
872+
pager = client.{{ method_name }}(request={}, retry=retry, timeout=timeout)
871873

872874
assert pager._metadata == expected_metadata
875+
assert pager._retry == retry
876+
assert pager._timeout == timeout
873877

874878
results = list(pager)
875879
assert len(results) == 6

packages/gapic-generator/noxfile.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -434,7 +434,9 @@ def showcase_mypy(
434434
"""Perform typecheck analysis on the generated Showcase library."""
435435

436436
# Install pytest and gapic-generator-python
437-
session.install("mypy", "types-pkg-resources", "types-protobuf", "types-requests", "types-dataclasses")
437+
# TODO(https://github.com/googleapis/gapic-generator-python/issues/2066):
438+
# Ignore release of mypy 1.11.0 which may have a regression
439+
session.install("mypy!=1.11.0", "types-pkg-resources", "types-protobuf", "types-requests", "types-dataclasses")
438440

439441
with showcase_library(session, templates=templates, other_opts=other_opts) as lib:
440442
session.chdir(lib)

0 commit comments

Comments
 (0)