Skip to content

Commit 11d06de

Browse files
committed
Load all pages for operations that paginate.
1 parent ee40290 commit 11d06de

File tree

2 files changed

+34
-6
lines changed

2 files changed

+34
-6
lines changed

awsshell/wizard.py

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -250,16 +250,25 @@ def _handle_request_retrieval(self):
250250
req = self.retrieval['Resource']
251251
# get client from wizard's cache
252252
client = self._cached_creator.create_client(req['Service'])
253-
# get the operation from the client
254-
operation = getattr(client, xform_name(req['Operation']))
253+
operation_name = xform_name(req['Operation'])
255254
# get any parameters
256255
parameters = req.get('Parameters', {})
257256
env_parameters = \
258257
self._env.resolve_parameters(req.get('EnvParameters', {}))
259-
# union of parameters and env_parameters, conflicts favor env_params
258+
# union of parameters and env_parameters, conflicts favor env params
260259
parameters = dict(parameters, **env_parameters)
261-
# execute operation passing all parameters
262-
return operation(**parameters)
260+
# if the operation supports pagination, load all results upfront
261+
if client.can_paginate(operation_name):
262+
# get paginator and create iterator
263+
paginator = client.get_paginator(operation_name)
264+
page_iterator = paginator.paginate(**parameters)
265+
# scroll through all pages combining them
266+
return page_iterator.build_full_result()
267+
else:
268+
# get the operation from the client
269+
operation = getattr(client, operation_name)
270+
# execute operation passing all parameters
271+
return operation(**parameters)
263272

264273
def _handle_retrieval(self):
265274
# In case of no retrieval, empty dict

tests/unit/test_wizard.py

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import mock
22
import pytest
3+
from botocore.session import Session
34
from awsshell.utils import FileReadError
45
from awsshell.wizard import stage_error_handler
56
from awsshell.interaction import InteractionException
@@ -138,7 +139,8 @@ def test_static_retrieval_with_query(wizard_spec, loader):
138139

139140
def test_request_retrieval(wizard_spec_request):
140141
# Tests that retrieval requests are parsed and call the correct operation
141-
mock_session = mock.Mock()
142+
mock_session = mock.Mock(spec=Session)
143+
mock_session.create_client.return_value.can_paginate.return_value = False
142144
mock_request = mock_session.create_client.return_value.create_rest_api
143145
mock_request.return_value = {'id': 'api id', 'name': 'random name'}
144146

@@ -148,6 +150,23 @@ def test_request_retrieval(wizard_spec_request):
148150
mock_request.assert_called_once_with(param='value', name='new api name')
149151

150152

153+
def test_request_retrieval_paginate(wizard_spec_request):
154+
# Tests that retrieval requests are parsed and call the correct operation
155+
mock_session = mock.Mock(spec=Session)
156+
mock_client = mock_session.create_client.return_value
157+
mock_client.can_paginate.return_value = True
158+
mock_paginator = mock_client.get_paginator.return_value
159+
mock_iterator = mock_paginator.paginate.return_value
160+
result = {'id': 'api id', 'name': 'random name'}
161+
mock_iterator.build_full_result.return_value = result
162+
paginate = mock_paginator.paginate
163+
164+
loader = WizardLoader(mock_session)
165+
wizard = loader.create_wizard(wizard_spec_request)
166+
wizard.execute()
167+
paginate.assert_called_once_with(param='value', name='new api name')
168+
169+
151170
def test_next_stage_resolution(wizard_spec, loader):
152171
# Test that the stage can resolve the next stage from env
153172
wizard_spec['Stages'][0]['Retrieval']['Path'] = '[0]'

0 commit comments

Comments
 (0)