cli2 3.3.29__tar.gz → 3.3.31__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {cli2-3.3.29/cli2.egg-info → cli2-3.3.31}/PKG-INFO +1 -1
- {cli2-3.3.29 → cli2-3.3.31}/cli2/client.py +23 -7
- {cli2-3.3.29 → cli2-3.3.31}/cli2/test_client.py +11 -2
- {cli2-3.3.29 → cli2-3.3.31/cli2.egg-info}/PKG-INFO +1 -1
- {cli2-3.3.29 → cli2-3.3.31}/setup.py +1 -1
- {cli2-3.3.29 → cli2-3.3.31}/MANIFEST.in +0 -0
- {cli2-3.3.29 → cli2-3.3.31}/README.rst +0 -0
- {cli2-3.3.29 → cli2-3.3.31}/classifiers.txt +0 -0
- {cli2-3.3.29 → cli2-3.3.31}/cli2/__init__.py +0 -0
- {cli2-3.3.29 → cli2-3.3.31}/cli2/argument.py +0 -0
- {cli2-3.3.29 → cli2-3.3.31}/cli2/asyncio.py +0 -0
- {cli2-3.3.29 → cli2-3.3.31}/cli2/cli.py +0 -0
- {cli2-3.3.29 → cli2-3.3.31}/cli2/colors.py +0 -0
- {cli2-3.3.29 → cli2-3.3.31}/cli2/command.py +0 -0
- {cli2-3.3.29 → cli2-3.3.31}/cli2/configuration.py +0 -0
- {cli2-3.3.29 → cli2-3.3.31}/cli2/decorators.py +0 -0
- {cli2-3.3.29 → cli2-3.3.31}/cli2/display.py +0 -0
- {cli2-3.3.29 → cli2-3.3.31}/cli2/entry_point.py +0 -0
- {cli2-3.3.29 → cli2-3.3.31}/cli2/example_client.py +0 -0
- {cli2-3.3.29 → cli2-3.3.31}/cli2/example_client_complex.py +0 -0
- {cli2-3.3.29 → cli2-3.3.31}/cli2/example_nesting.py +0 -0
- {cli2-3.3.29 → cli2-3.3.31}/cli2/example_obj.py +0 -0
- {cli2-3.3.29 → cli2-3.3.31}/cli2/group.py +0 -0
- {cli2-3.3.29 → cli2-3.3.31}/cli2/logging.py +0 -0
- {cli2-3.3.29 → cli2-3.3.31}/cli2/node.py +0 -0
- {cli2-3.3.29 → cli2-3.3.31}/cli2/overrides.py +0 -0
- {cli2-3.3.29 → cli2-3.3.31}/cli2/sphinx.py +0 -0
- {cli2-3.3.29 → cli2-3.3.31}/cli2/table.py +0 -0
- {cli2-3.3.29 → cli2-3.3.31}/cli2/test.py +0 -0
- {cli2-3.3.29 → cli2-3.3.31}/cli2/test_cli.py +0 -0
- {cli2-3.3.29 → cli2-3.3.31}/cli2/test_command.py +0 -0
- {cli2-3.3.29 → cli2-3.3.31}/cli2/test_configuration.py +0 -0
- {cli2-3.3.29 → cli2-3.3.31}/cli2/test_decorators.py +0 -0
- {cli2-3.3.29 → cli2-3.3.31}/cli2/test_display.py +0 -0
- {cli2-3.3.29 → cli2-3.3.31}/cli2/test_entry_point.py +0 -0
- {cli2-3.3.29 → cli2-3.3.31}/cli2/test_group.py +0 -0
- {cli2-3.3.29 → cli2-3.3.31}/cli2/test_inject.py +0 -0
- {cli2-3.3.29 → cli2-3.3.31}/cli2/test_node.py +0 -0
- {cli2-3.3.29 → cli2-3.3.31}/cli2/test_table.py +0 -0
- {cli2-3.3.29 → cli2-3.3.31}/cli2.egg-info/SOURCES.txt +0 -0
- {cli2-3.3.29 → cli2-3.3.31}/cli2.egg-info/dependency_links.txt +0 -0
- {cli2-3.3.29 → cli2-3.3.31}/cli2.egg-info/entry_points.txt +0 -0
- {cli2-3.3.29 → cli2-3.3.31}/cli2.egg-info/requires.txt +0 -0
- {cli2-3.3.29 → cli2-3.3.31}/cli2.egg-info/top_level.txt +0 -0
- {cli2-3.3.29 → cli2-3.3.31}/setup.cfg +0 -0
|
@@ -75,9 +75,14 @@ class Paginator:
|
|
|
75
75
|
.. py:attribute:: model
|
|
76
76
|
|
|
77
77
|
:py:class:`Model` class or ``dict`` by default.
|
|
78
|
+
|
|
79
|
+
.. py:attribute:: callback
|
|
80
|
+
|
|
81
|
+
Callback called for every item.
|
|
78
82
|
"""
|
|
79
83
|
|
|
80
|
-
def __init__(self, client, url, params=None, model=None, expressions=None
|
|
84
|
+
def __init__(self, client, url, params=None, model=None, expressions=None,
|
|
85
|
+
callback=None):
|
|
81
86
|
"""
|
|
82
87
|
Initialize a paginator object with a client on a URL with parameters.
|
|
83
88
|
|
|
@@ -93,6 +98,7 @@ class Paginator:
|
|
|
93
98
|
self.page_start = 1
|
|
94
99
|
self.per_page = None
|
|
95
100
|
self.initialized = False
|
|
101
|
+
self.callback = callback
|
|
96
102
|
self.expressions = []
|
|
97
103
|
for expression in (expressions or []):
|
|
98
104
|
if not isinstance(expression, Expression):
|
|
@@ -270,6 +276,8 @@ class Paginator:
|
|
|
270
276
|
"""
|
|
271
277
|
Asynchronous iterator.
|
|
272
278
|
"""
|
|
279
|
+
callback = callback or self.callback
|
|
280
|
+
|
|
273
281
|
if self._reverse and not self.total_pages:
|
|
274
282
|
first_page_response = await self.page_response(1)
|
|
275
283
|
page = self.total_pages
|
|
@@ -287,6 +295,8 @@ class Paginator:
|
|
|
287
295
|
|
|
288
296
|
for item in items:
|
|
289
297
|
if not python_filter or python_filter.matches(item):
|
|
298
|
+
if callback:
|
|
299
|
+
callback(item)
|
|
290
300
|
yield item
|
|
291
301
|
|
|
292
302
|
if self._reverse:
|
|
@@ -298,6 +308,8 @@ class Paginator:
|
|
|
298
308
|
items = self.response_items(first_page_response)
|
|
299
309
|
for item in reversed(items):
|
|
300
310
|
if not python_filter or python_filter.matches(item):
|
|
311
|
+
if callback:
|
|
312
|
+
callback(item)
|
|
301
313
|
yield item
|
|
302
314
|
break
|
|
303
315
|
else:
|
|
@@ -1038,7 +1050,7 @@ class Handler:
|
|
|
1038
1050
|
raise response
|
|
1039
1051
|
# httpx session is rendered unusable after a TransportError
|
|
1040
1052
|
if isinstance(response, httpx.TransportError):
|
|
1041
|
-
log.warn('reconnect',
|
|
1053
|
+
log.warn('reconnect', error=repr(response))
|
|
1042
1054
|
await client.client_reset()
|
|
1043
1055
|
return
|
|
1044
1056
|
|
|
@@ -1337,15 +1349,20 @@ class Client(metaclass=ClientMetaclass):
|
|
|
1337
1349
|
By default, this method does nothing. Implement it to your likings.
|
|
1338
1350
|
|
|
1339
1351
|
This method is supposed to return the token, but doesn't do anything
|
|
1340
|
-
with it by itself
|
|
1352
|
+
with it by itself.
|
|
1353
|
+
|
|
1354
|
+
You also need to implement the :py:meth:`client_token_apply` which is
|
|
1355
|
+
in charge of updating the actual httpx client object with the said
|
|
1356
|
+
token.
|
|
1341
1357
|
|
|
1342
1358
|
.. code-block::
|
|
1343
1359
|
|
|
1344
1360
|
async def token_get(self):
|
|
1345
1361
|
response = await self.post('/login', dict(...))
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1362
|
+
return response.json()['token']
|
|
1363
|
+
|
|
1364
|
+
def client_token_apply(self, client):
|
|
1365
|
+
client.headers['X-ApiKey'] = self.token
|
|
1349
1366
|
"""
|
|
1350
1367
|
raise NotImplementedError()
|
|
1351
1368
|
|
|
@@ -1406,7 +1423,6 @@ class Client(metaclass=ClientMetaclass):
|
|
|
1406
1423
|
the response, set to False if you want only 1 try.
|
|
1407
1424
|
:param accepts: Override for :py:attr:`Handler.accepts`
|
|
1408
1425
|
:param refuses: Override for :py:attr:`Handler.refuses`
|
|
1409
|
-
:param retries: Override for :py:attr:`Handler.retries`
|
|
1410
1426
|
:param tries: Override for :py:attr:`Handler.tries`
|
|
1411
1427
|
:param backoff: Override for :py:attr:`Handler.backoff`
|
|
1412
1428
|
:param semaphore: Override for :py:attr:`Client.semaphore`
|
|
@@ -266,7 +266,10 @@ async def test_handler(client_class):
|
|
|
266
266
|
|
|
267
267
|
assert not client.client_reset.await_count
|
|
268
268
|
result = await handler(client, httpx.TransportError('foo'), 0, [], log)
|
|
269
|
-
log.warn.assert_called_once_with(
|
|
269
|
+
log.warn.assert_called_once_with(
|
|
270
|
+
'reconnect',
|
|
271
|
+
error="TransportError('foo')",
|
|
272
|
+
)
|
|
270
273
|
assert not result
|
|
271
274
|
assert client.client_reset.await_count == 1
|
|
272
275
|
|
|
@@ -344,7 +347,13 @@ async def test_pagination(httpx_mock):
|
|
|
344
347
|
httpx_mock.add_response(url='http://lol/?page=2', json=[dict(a=2)])
|
|
345
348
|
httpx_mock.add_response(url='http://lol/?page=3', json=[])
|
|
346
349
|
client = Client(base_url='http://lol')
|
|
347
|
-
|
|
350
|
+
paginator = client.paginate('/')
|
|
351
|
+
paginator.callback = mock.Mock()
|
|
352
|
+
assert await paginator.list() == [dict(a=1), dict(a=2)]
|
|
353
|
+
assert paginator.callback.call_args_list == [
|
|
354
|
+
mock.call({'a': 1}),
|
|
355
|
+
mock.call({'a': 2})
|
|
356
|
+
]
|
|
348
357
|
|
|
349
358
|
|
|
350
359
|
@pytest.mark.asyncio
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|