Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -56,19 +56,17 @@ class {{ method.name }}Pager:
def __getattr__(self, name: str) -> Any:
return getattr(self._response, name)

def __iter__(self) -> {{ method.paged_result_field.ident | replace('Sequence', 'Iterable') }}:
while True:
# Iterate through the results on this response.
for result in self._response.{{ method.paged_result_field.name }}:
yield result

# Sanity check: Is this the last page? If so, we are done.
if not self._response.next_page_token:
break

# Get the next page.
@property
def pages(self) -> Iterable[{{ method.output.ident }}]:
yield self._response
while self._response.next_page_token:
self._request.page_token = self._response.next_page_token
self._response = self._method(self._request)
yield self._response

def __iter__(self) -> {{ method.paged_result_field.ident | replace('Sequence', 'Iterable') }}:
for page in self.pages:
yield from page.{{ method.paged_result_field.name }}

def __repr__(self) -> str:
return '{0}<{1!r}>'.format(self.__class__.__name__, self._response)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,12 @@ class {{ message.name }}({{ p }}.Message):
{% endif %}
{% endfor -%}

{% if "next_page_token" in message.fields.values()|map(attribute='name') %}
@property
def raw_page(self):
return self
{% endif %}

{# Iterate over fields. -#}
{% for field in message.fields.values() -%}
{% if field.map -%}
Expand Down
49 changes: 47 additions & 2 deletions gapic/templates/tests/unit/$name_$version/$sub/test_$service.py.j2
Original file line number Diff line number Diff line change
Expand Up @@ -211,8 +211,53 @@ def test_{{ method.name|snake_case }}_pager():
)]
assert len(results) == 6
assert all([isinstance(i, {{ method.paged_result_field.message.ident }})
for i in results])
{% endif %} {#- method.paged_response_field #}
for i in results])

def test_{{ method.name|snake_case }}_pages():
client = {{ service.client_name }}(
credentials=credentials.AnonymousCredentials,
)

# Mock the actual call within the gRPC stub, and fake the request.
with mock.patch.object(
type(client._transport.{{ method.name|snake_case }}),
'__call__') as call:
# Set the response to a series of pages.
call.side_effect = (
{{ method.output.ident }}(
{{ method.paged_result_field.name }}=[
{{ method.paged_result_field.message.ident }}(),
{{ method.paged_result_field.message.ident }}(),
{{ method.paged_result_field.message.ident }}(),
],
next_page_token='abc',
),
{{ method.output.ident }}(
{{ method.paged_result_field.name }}=[],
next_page_token='def',
),
{{ method.output.ident }}(
{{ method.paged_result_field.name }}=[
{{ method.paged_result_field.message.ident }}(),
],
next_page_token='ghi',
),
{{ method.output.ident }}(
{{ method.paged_result_field.name }}=[
{{ method.paged_result_field.message.ident }}(),
{{ method.paged_result_field.message.ident }}(),
],
),
RuntimeError,
)
pages = list(client.{{ method.name|snake_case }}(request={}).pages)
for page, token in zip(pages, ['abc','def','ghi', '']):
assert page.raw_page.next_page_token == token
{% elif method.lro and "next_page_token" in method.lro.response_type.fields.keys() %}
def test_{{ method.name|snake_case }}_raw_page_lro():
response = {{ method.lro.response_type.ident }}()
assert response.raw_page is response
{% endif %} {#- method.paged_result_field #}

{% endfor -%} {#- method in methods #}

Expand Down
22 changes: 21 additions & 1 deletion tests/system/test_pagination.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,31 @@


def test_pagination(echo):
text = 'The rain in Wales falls mainly on the snails.'
text = 'The hail in Wales falls mainly on the snails.'
results = [i for i in echo.paged_expand({
'content': text,
'page_size': 3,
})]
assert len(results) == 9
assert results == [showcase.EchoResponse(content=i)
for i in text.split(' ')]


def test_pagination_pages(echo):
text = "The hail in Wales falls mainly on the snails."
page_results = list(echo.paged_expand({
'content': text,
'page_size': 3,
}).pages)

assert len(page_results) == 3
assert not page_results[-1].next_page_token

# The monolithic surface uses a wrapper type that needs an explicit property
# for a 'raw_page': we need to duplicate that interface, even though the
# architecture is different.
assert page_results[0].raw_page is page_results[0]

results = [r for p in page_results for r in p.responses]
assert results == [showcase.EchoResponse(content=i)
for i in text.split(' ')]