cli2 3.3.37__tar.gz → 3.3.41__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.37/cli2.egg-info → cli2-3.3.41}/PKG-INFO +13 -2
- {cli2-3.3.37 → cli2-3.3.41}/cli2/client.py +23 -88
- {cli2-3.3.37 → cli2-3.3.41}/cli2/test_client.py +53 -76
- {cli2-3.3.37 → cli2-3.3.41/cli2.egg-info}/PKG-INFO +13 -2
- {cli2-3.3.37 → cli2-3.3.41}/setup.py +1 -1
- {cli2-3.3.37 → cli2-3.3.41}/MANIFEST.in +0 -0
- {cli2-3.3.37 → cli2-3.3.41}/README.rst +0 -0
- {cli2-3.3.37 → cli2-3.3.41}/classifiers.txt +0 -0
- {cli2-3.3.37 → cli2-3.3.41}/cli2/__init__.py +0 -0
- {cli2-3.3.37 → cli2-3.3.41}/cli2/argument.py +0 -0
- {cli2-3.3.37 → cli2-3.3.41}/cli2/asyncio.py +0 -0
- {cli2-3.3.37 → cli2-3.3.41}/cli2/cli.py +0 -0
- {cli2-3.3.37 → cli2-3.3.41}/cli2/colors.py +0 -0
- {cli2-3.3.37 → cli2-3.3.41}/cli2/command.py +0 -0
- {cli2-3.3.37 → cli2-3.3.41}/cli2/configuration.py +0 -0
- {cli2-3.3.37 → cli2-3.3.41}/cli2/decorators.py +0 -0
- {cli2-3.3.37 → cli2-3.3.41}/cli2/display.py +0 -0
- {cli2-3.3.37 → cli2-3.3.41}/cli2/entry_point.py +0 -0
- {cli2-3.3.37 → cli2-3.3.41}/cli2/example_client.py +0 -0
- {cli2-3.3.37 → cli2-3.3.41}/cli2/example_client_complex.py +0 -0
- {cli2-3.3.37 → cli2-3.3.41}/cli2/example_nesting.py +0 -0
- {cli2-3.3.37 → cli2-3.3.41}/cli2/example_obj.py +0 -0
- {cli2-3.3.37 → cli2-3.3.41}/cli2/group.py +0 -0
- {cli2-3.3.37 → cli2-3.3.41}/cli2/logging.py +0 -0
- {cli2-3.3.37 → cli2-3.3.41}/cli2/node.py +0 -0
- {cli2-3.3.37 → cli2-3.3.41}/cli2/overrides.py +0 -0
- {cli2-3.3.37 → cli2-3.3.41}/cli2/sphinx.py +0 -0
- {cli2-3.3.37 → cli2-3.3.41}/cli2/table.py +0 -0
- {cli2-3.3.37 → cli2-3.3.41}/cli2/test.py +0 -0
- {cli2-3.3.37 → cli2-3.3.41}/cli2/test_cli.py +0 -0
- {cli2-3.3.37 → cli2-3.3.41}/cli2/test_command.py +0 -0
- {cli2-3.3.37 → cli2-3.3.41}/cli2/test_configuration.py +0 -0
- {cli2-3.3.37 → cli2-3.3.41}/cli2/test_decorators.py +0 -0
- {cli2-3.3.37 → cli2-3.3.41}/cli2/test_display.py +0 -0
- {cli2-3.3.37 → cli2-3.3.41}/cli2/test_entry_point.py +0 -0
- {cli2-3.3.37 → cli2-3.3.41}/cli2/test_group.py +0 -0
- {cli2-3.3.37 → cli2-3.3.41}/cli2/test_inject.py +0 -0
- {cli2-3.3.37 → cli2-3.3.41}/cli2/test_node.py +0 -0
- {cli2-3.3.37 → cli2-3.3.41}/cli2/test_table.py +0 -0
- {cli2-3.3.37 → cli2-3.3.41}/cli2.egg-info/SOURCES.txt +0 -0
- {cli2-3.3.37 → cli2-3.3.41}/cli2.egg-info/dependency_links.txt +0 -0
- {cli2-3.3.37 → cli2-3.3.41}/cli2.egg-info/entry_points.txt +0 -0
- {cli2-3.3.37 → cli2-3.3.41}/cli2.egg-info/requires.txt +0 -0
- {cli2-3.3.37 → cli2-3.3.41}/cli2.egg-info/top_level.txt +0 -0
- {cli2-3.3.37 → cli2-3.3.41}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.2
|
|
2
2
|
Name: cli2
|
|
3
|
-
Version: 3.3.
|
|
3
|
+
Version: 3.3.41
|
|
4
4
|
Summary: image:: https://yourlabs.io/oss/cli2/badges/master/pipeline.svg
|
|
5
5
|
Home-page: https://yourlabs.io/oss/cli2
|
|
6
6
|
Author: James Pic
|
|
@@ -23,6 +23,17 @@ Requires-Dist: pytest-cov; extra == "test"
|
|
|
23
23
|
Requires-Dist: pytest-mock; extra == "test"
|
|
24
24
|
Requires-Dist: pytest-asyncio; extra == "test"
|
|
25
25
|
Requires-Dist: pytest-httpx; extra == "test"
|
|
26
|
+
Dynamic: author
|
|
27
|
+
Dynamic: author-email
|
|
28
|
+
Dynamic: description
|
|
29
|
+
Dynamic: description-content-type
|
|
30
|
+
Dynamic: home-page
|
|
31
|
+
Dynamic: keywords
|
|
32
|
+
Dynamic: license
|
|
33
|
+
Dynamic: provides-extra
|
|
34
|
+
Dynamic: requires-dist
|
|
35
|
+
Dynamic: requires-python
|
|
36
|
+
Dynamic: summary
|
|
26
37
|
|
|
27
38
|
.. image:: https://yourlabs.io/oss/cli2/badges/master/pipeline.svg
|
|
28
39
|
:target: https://yourlabs.io/oss/cli2/pipelines
|
|
@@ -34,19 +34,11 @@ class Paginator:
|
|
|
34
34
|
"""
|
|
35
35
|
Generic pagination class.
|
|
36
36
|
|
|
37
|
-
|
|
38
|
-
|
|
37
|
+
Should work with most paginations by default, if you're extending this then
|
|
38
|
+
override:
|
|
39
39
|
|
|
40
|
-
-
|
|
41
|
-
|
|
42
|
-
:py:meth:`~Client.pagination_parameters` methods
|
|
43
|
-
|
|
44
|
-
- or also, per model, in the :py:class:`~Model` class with the
|
|
45
|
-
:py:meth:`~Model.pagination_initialize` and
|
|
46
|
-
:py:meth:`~Model.pagination_parameters` methods
|
|
47
|
-
|
|
48
|
-
Refer to :py:meth:`pagination_parameters` and
|
|
49
|
-
:py:meth:`pagination_initialize` for details.
|
|
40
|
+
- :py:meth:`~Paginator.pagination_initialize`
|
|
41
|
+
- :py:meth:`~Paginator.pagination_parameters`
|
|
50
42
|
|
|
51
43
|
.. py:attribute:: total_pages
|
|
52
44
|
|
|
@@ -76,17 +68,13 @@ class Paginator:
|
|
|
76
68
|
|
|
77
69
|
:py:class:`Model` class or ``dict`` by default.
|
|
78
70
|
|
|
79
|
-
.. py:attribute::
|
|
80
|
-
|
|
81
|
-
Callback called for every item after filtering.
|
|
82
|
-
|
|
83
|
-
.. py:attribute:: prefilter
|
|
71
|
+
.. py:attribute:: callback
|
|
84
72
|
|
|
85
|
-
|
|
73
|
+
Async callback called for every item before filtering by expressions.
|
|
86
74
|
"""
|
|
87
75
|
|
|
88
76
|
def __init__(self, client, url, params=None, model=None, expressions=None,
|
|
89
|
-
|
|
77
|
+
callback=None):
|
|
90
78
|
"""
|
|
91
79
|
Initialize a paginator object with a client on a URL with parameters.
|
|
92
80
|
|
|
@@ -102,8 +90,7 @@ class Paginator:
|
|
|
102
90
|
self.page_start = 1
|
|
103
91
|
self.per_page = None
|
|
104
92
|
self.initialized = False
|
|
105
|
-
self.
|
|
106
|
-
self.postfilter = postfilter
|
|
93
|
+
self.callback = callback
|
|
107
94
|
self.expressions = []
|
|
108
95
|
for expression in (expressions or []):
|
|
109
96
|
if not isinstance(expression, Expression):
|
|
@@ -180,12 +167,6 @@ class Paginator:
|
|
|
180
167
|
|
|
181
168
|
:param data: Data of the first response
|
|
182
169
|
"""
|
|
183
|
-
try:
|
|
184
|
-
self.model.pagination_initialize
|
|
185
|
-
except AttributeError:
|
|
186
|
-
return self.client.pagination_initialize(self, data)
|
|
187
|
-
else:
|
|
188
|
-
return self.model.pagination_initialize(self, data)
|
|
189
170
|
|
|
190
171
|
def pagination_parameters(self, page_number):
|
|
191
172
|
"""
|
|
@@ -199,15 +180,12 @@ class Paginator:
|
|
|
199
180
|
|
|
200
181
|
.. code-block:: python
|
|
201
182
|
|
|
202
|
-
def pagination_parameters(self,
|
|
183
|
+
def pagination_parameters(self, page_number):
|
|
184
|
+
# this is the default implementation
|
|
203
185
|
return dict(page=page_number)
|
|
204
186
|
"""
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
except AttributeError:
|
|
208
|
-
return self.client.pagination_parameters(self, page_number)
|
|
209
|
-
else:
|
|
210
|
-
return self.model.pagination_parameters(self, page_number)
|
|
187
|
+
if page_number > 1:
|
|
188
|
+
return dict(page=page_number)
|
|
211
189
|
|
|
212
190
|
def response_items(self, response):
|
|
213
191
|
"""
|
|
@@ -277,28 +255,27 @@ class Paginator:
|
|
|
277
255
|
await self.initialize(response)
|
|
278
256
|
return response
|
|
279
257
|
|
|
280
|
-
async def __aiter__(self,
|
|
258
|
+
async def __aiter__(self, callback=None):
|
|
281
259
|
"""
|
|
282
260
|
Asynchronous iterator.
|
|
283
261
|
"""
|
|
284
|
-
|
|
285
|
-
postfilter = postfilter or self.postfilter
|
|
262
|
+
callback = callback or self.callback
|
|
286
263
|
|
|
287
264
|
if self._reverse and not self.total_pages:
|
|
288
265
|
first_page_response = await self.page_response(1)
|
|
289
266
|
page = self.total_pages
|
|
267
|
+
if not self.total_pages:
|
|
268
|
+
raise Exception('Reverse pagination without total_pages')
|
|
290
269
|
else:
|
|
291
270
|
page = self.page_start
|
|
292
271
|
|
|
293
272
|
python_filter = self.python_filter()
|
|
294
273
|
|
|
295
274
|
async def yielder(items):
|
|
275
|
+
if callback:
|
|
276
|
+
await asyncio.gather(*[callback(item) for item in items])
|
|
296
277
|
for item in items:
|
|
297
|
-
if prefilter:
|
|
298
|
-
await async_resolve(prefilter(item))
|
|
299
278
|
if not python_filter or python_filter.matches(item):
|
|
300
|
-
if postfilter:
|
|
301
|
-
await async_resolve(postfilter(item))
|
|
302
279
|
yield item
|
|
303
280
|
|
|
304
281
|
while items := await self.page_items(page):
|
|
@@ -836,32 +813,6 @@ class Model(metaclass=ModelMetaclass):
|
|
|
836
813
|
"""
|
|
837
814
|
return cls.paginator(cls.client, url, params, cls, expressions)
|
|
838
815
|
|
|
839
|
-
@classmethod
|
|
840
|
-
def pagination_initialize(cls, paginator, data):
|
|
841
|
-
"""
|
|
842
|
-
Implement Model-specific pagination initialization here.
|
|
843
|
-
|
|
844
|
-
Otherwise, :py:meth:`Client.pagination_initialize` will
|
|
845
|
-
take place.
|
|
846
|
-
|
|
847
|
-
Refer to :py:meth:`Paginator.pagination_initialize` for
|
|
848
|
-
details.
|
|
849
|
-
"""
|
|
850
|
-
cls.client.pagination_initialize(paginator, data)
|
|
851
|
-
|
|
852
|
-
@classmethod
|
|
853
|
-
def pagination_parameters(cls, paginator, page_number):
|
|
854
|
-
"""
|
|
855
|
-
Implement Model-specific pagination parameters here.
|
|
856
|
-
|
|
857
|
-
Otherwise, :py:meth:`Client.pagination_parameters` will
|
|
858
|
-
take place.
|
|
859
|
-
|
|
860
|
-
Refer to :py:meth:`Paginator.pagination_parameters` for
|
|
861
|
-
details.
|
|
862
|
-
"""
|
|
863
|
-
return cls.client.pagination_parameters(paginator, page_number)
|
|
864
|
-
|
|
865
816
|
@property
|
|
866
817
|
def cli2_display(self):
|
|
867
818
|
return self.data
|
|
@@ -1179,9 +1130,7 @@ class Client(metaclass=ClientMetaclass):
|
|
|
1179
1130
|
|
|
1180
1131
|
.. py:attribute:: paginator
|
|
1181
1132
|
|
|
1182
|
-
:py:class:`Paginator` class
|
|
1183
|
-
implement :py:meth:`pagination_initialize` and
|
|
1184
|
-
:py:meth:`pagination_parameters`.
|
|
1133
|
+
:py:class:`Paginator` class
|
|
1185
1134
|
|
|
1186
1135
|
.. py:attribute:: semaphore
|
|
1187
1136
|
|
|
@@ -1607,7 +1556,8 @@ class Client(metaclass=ClientMetaclass):
|
|
|
1607
1556
|
""" DELETE Request """
|
|
1608
1557
|
return await self.request('DELETE', url, *args, **kwargs)
|
|
1609
1558
|
|
|
1610
|
-
def paginate(self, url, params=None, model=None
|
|
1559
|
+
def paginate(self, url, *expressions, params=None, model=None,
|
|
1560
|
+
callback=None):
|
|
1611
1561
|
"""
|
|
1612
1562
|
Return a paginator to iterate over results
|
|
1613
1563
|
|
|
@@ -1615,23 +1565,8 @@ class Client(metaclass=ClientMetaclass):
|
|
|
1615
1565
|
:param params: GET parameters
|
|
1616
1566
|
:param model: Model class to cast for items
|
|
1617
1567
|
"""
|
|
1618
|
-
return self.paginator(self, url, params or {}, model or dict
|
|
1619
|
-
|
|
1620
|
-
def pagination_parameters(self, paginator, page_number):
|
|
1621
|
-
"""
|
|
1622
|
-
Implement Model-specific pagination parameters here.
|
|
1623
|
-
|
|
1624
|
-
Refer to :py:meth:`Paginator.pagination_parameters` for
|
|
1625
|
-
details.
|
|
1626
|
-
"""
|
|
1627
|
-
|
|
1628
|
-
def pagination_initialize(self, paginator, data):
|
|
1629
|
-
"""
|
|
1630
|
-
Implement Model-specific pagination initialization here.
|
|
1631
|
-
|
|
1632
|
-
Refer to :py:meth:`Paginator.pagination_initialize` for
|
|
1633
|
-
details.
|
|
1634
|
-
"""
|
|
1568
|
+
return self.paginator(self, url, params or {}, model or dict,
|
|
1569
|
+
expressions, callback)
|
|
1635
1570
|
|
|
1636
1571
|
|
|
1637
1572
|
class Expression:
|
|
@@ -49,6 +49,7 @@ async def test_client_cli(client_class, httpx_mock):
|
|
|
49
49
|
assert isinstance(result.client, client_class)
|
|
50
50
|
|
|
51
51
|
httpx_mock.add_response(url='http://lol/', json=[dict(a=1)])
|
|
52
|
+
httpx_mock.add_response(url='http://lol/?page=2', json=[])
|
|
52
53
|
await client_class.cli['testmodel']['find'].async_call()
|
|
53
54
|
|
|
54
55
|
class TestModel2(client_class.Model):
|
|
@@ -124,6 +125,7 @@ async def test_async_factory(httpx_mock):
|
|
|
124
125
|
url_list = '/2'
|
|
125
126
|
|
|
126
127
|
httpx_mock.add_response(url='http://bar/2', json=[dict(a=1)])
|
|
128
|
+
httpx_mock.add_response(url='http://bar/2?page=2', json=[])
|
|
127
129
|
await TestClient.cli['testmodel']['find'].async_call()
|
|
128
130
|
|
|
129
131
|
|
|
@@ -369,23 +371,21 @@ async def test_token(httpx_mock):
|
|
|
369
371
|
|
|
370
372
|
@pytest.mark.asyncio
|
|
371
373
|
async def test_pagination(httpx_mock):
|
|
372
|
-
httpx_mock.add_response(url='http://lol
|
|
374
|
+
httpx_mock.add_response(url='http://lol/', json=[dict(a=1)])
|
|
373
375
|
httpx_mock.add_response(url='http://lol/?page=2', json=[dict(a=2)])
|
|
374
376
|
httpx_mock.add_response(url='http://lol/?page=3', json=[])
|
|
375
377
|
client = Client(base_url='http://lol')
|
|
376
|
-
paginator = client.paginate('/')
|
|
377
378
|
|
|
378
|
-
def
|
|
379
|
+
async def callback(item):
|
|
379
380
|
item['b'] = item['a']
|
|
380
381
|
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
382
|
+
paginator = client.paginate(
|
|
383
|
+
'/',
|
|
384
|
+
lambda item: item['b'] == 2,
|
|
385
|
+
callback=callback,
|
|
386
|
+
)
|
|
386
387
|
assert await paginator.list() == [
|
|
387
|
-
dict(a=
|
|
388
|
-
dict(a=2, b=2, c=2)
|
|
388
|
+
dict(a=2, b=2)
|
|
389
389
|
]
|
|
390
390
|
|
|
391
391
|
|
|
@@ -406,11 +406,12 @@ def test_paginator(client_class):
|
|
|
406
406
|
|
|
407
407
|
@pytest.mark.asyncio
|
|
408
408
|
async def test_pagination_initialize(httpx_mock):
|
|
409
|
-
httpx_mock.add_response(url='http://lol
|
|
409
|
+
httpx_mock.add_response(url='http://lol/', json=dict(
|
|
410
410
|
total_pages=2,
|
|
411
411
|
items=[dict(a=1)],
|
|
412
412
|
))
|
|
413
413
|
httpx_mock.add_response(url='http://lol/?page=2', json=[dict(a=2)])
|
|
414
|
+
httpx_mock.add_response(url='http://lol/?page=3', json=[])
|
|
414
415
|
|
|
415
416
|
class PaginatedClient(Client):
|
|
416
417
|
def pagination_initialize(self, paginator, data):
|
|
@@ -419,7 +420,7 @@ async def test_pagination_initialize(httpx_mock):
|
|
|
419
420
|
client = PaginatedClient(base_url='http://lol')
|
|
420
421
|
assert await client.paginate('/').list() == [dict(a=1), dict(a=2)]
|
|
421
422
|
|
|
422
|
-
httpx_mock.add_response(url='http://lol
|
|
423
|
+
httpx_mock.add_response(url='http://lol/', json=dict(
|
|
423
424
|
total_pages=2,
|
|
424
425
|
items=[dict(a=1)],
|
|
425
426
|
))
|
|
@@ -429,7 +430,7 @@ async def test_pagination_initialize(httpx_mock):
|
|
|
429
430
|
@pytest.mark.asyncio
|
|
430
431
|
async def test_token_get(httpx_mock):
|
|
431
432
|
httpx_mock.add_response(url='http://lol/token', json=dict(token=123))
|
|
432
|
-
httpx_mock.add_response(url='http://lol
|
|
433
|
+
httpx_mock.add_response(url='http://lol/', json=[])
|
|
433
434
|
|
|
434
435
|
class TokenClient(Client):
|
|
435
436
|
async def token_get(self):
|
|
@@ -446,7 +447,7 @@ async def test_pagination_model(httpx_mock):
|
|
|
446
447
|
class Model(dict):
|
|
447
448
|
pass
|
|
448
449
|
|
|
449
|
-
httpx_mock.add_response(url='http://lol
|
|
450
|
+
httpx_mock.add_response(url='http://lol/', json=[dict(a=2)])
|
|
450
451
|
httpx_mock.add_response(url='http://lol/?page=2', json=[])
|
|
451
452
|
client = Client(base_url='http://lol')
|
|
452
453
|
result = await client.paginate('/', model=Model).list()
|
|
@@ -465,47 +466,50 @@ async def test_pagination_patterns(httpx_mock):
|
|
|
465
466
|
# I'm dealing with APIs which have a different pagination system on
|
|
466
467
|
# different resources, and on some resources no pagination at all
|
|
467
468
|
# Would like to define that per model
|
|
469
|
+
|
|
470
|
+
class TotalPaginator(cli2.Paginator):
|
|
471
|
+
def pagination_initialize(self, data):
|
|
472
|
+
self.total_items = data['total_items']
|
|
473
|
+
self.per_page = len(data['items'])
|
|
474
|
+
|
|
468
475
|
class TotalModel(Client.Model):
|
|
476
|
+
paginator = TotalPaginator
|
|
469
477
|
url_list = '/foo'
|
|
470
478
|
|
|
471
|
-
@classmethod
|
|
472
|
-
def pagination_initialize(cls, paginator, data):
|
|
473
|
-
paginator.total_items = data['total_items']
|
|
474
|
-
paginator.per_page = len(data['items'])
|
|
475
|
-
|
|
476
479
|
httpx_mock.add_response(
|
|
477
|
-
url='http://lol/foo
|
|
480
|
+
url='http://lol/foo',
|
|
478
481
|
json=dict(total_items=2, items=[dict(a=1)]),
|
|
479
482
|
)
|
|
480
483
|
|
|
484
|
+
class PagesPaginator(cli2.Paginator):
|
|
485
|
+
def pagination_initialize(self, data):
|
|
486
|
+
self.total_pages = data['total_pages']
|
|
487
|
+
self.per_page = len(data['items'])
|
|
488
|
+
|
|
481
489
|
class Pages(Client.Model):
|
|
482
490
|
url_list = '/bar'
|
|
483
|
-
|
|
484
|
-
@classmethod
|
|
485
|
-
def pagination_initialize(cls, paginator, data):
|
|
486
|
-
paginator.total_pages = data['total_pages']
|
|
487
|
-
paginator.per_page = len(data['items'])
|
|
491
|
+
paginator = PagesPaginator
|
|
488
492
|
|
|
489
493
|
httpx_mock.add_response(
|
|
490
|
-
url='http://lol/bar
|
|
494
|
+
url='http://lol/bar',
|
|
491
495
|
json=dict(total_pages=1, items=[dict(a=1)]),
|
|
492
496
|
)
|
|
493
497
|
|
|
494
|
-
class
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
@classmethod
|
|
498
|
-
def pagination_initialize(cls, paginator, data):
|
|
499
|
-
paginator.total_items = data['total']
|
|
498
|
+
class OffsetPaginator(cli2.Paginator):
|
|
499
|
+
def pagination_initialize(self, data):
|
|
500
|
+
self.total_items = data['total']
|
|
500
501
|
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
paginator.per_page = 1
|
|
502
|
+
def pagination_parameters(self, page_number):
|
|
503
|
+
self.per_page = 1
|
|
504
504
|
return dict(
|
|
505
505
|
offset=(page_number - 1) * paginator.per_page,
|
|
506
506
|
limit=paginator.per_page,
|
|
507
507
|
)
|
|
508
508
|
|
|
509
|
+
class Offset(Client.Model):
|
|
510
|
+
url_list = '/off'
|
|
511
|
+
paginator = OffsetPaginator
|
|
512
|
+
|
|
509
513
|
httpx_mock.add_response(
|
|
510
514
|
url='http://lol/off?offset=0&limit=1',
|
|
511
515
|
json=dict(total=2, items=[dict(a=1)]),
|
|
@@ -530,39 +534,11 @@ async def test_pagination_patterns(httpx_mock):
|
|
|
530
534
|
assert paginator.per_page == 1
|
|
531
535
|
assert paginator.pagination_parameters(2) == dict(offset=1, limit=1)
|
|
532
536
|
|
|
533
|
-
class Key(Client.Model):
|
|
534
|
-
url_list = '/key'
|
|
535
|
-
|
|
536
|
-
@classmethod
|
|
537
|
-
def pagination_initialize(cls, paginator, data):
|
|
538
|
-
paginator.next_page = data['next_page']
|
|
539
|
-
paginator.total_pages = data['total']
|
|
540
|
-
|
|
541
|
-
@classmethod
|
|
542
|
-
def pagination_parameters(cls, paginator, page_number):
|
|
543
|
-
if page_number > 1:
|
|
544
|
-
return dict(next_page=paginator.next_page)
|
|
545
|
-
|
|
546
|
-
httpx_mock.add_response(
|
|
547
|
-
url='http://lol/key',
|
|
548
|
-
json=dict(total=2, items=[dict(a=1)], next_page='aoeu'),
|
|
549
|
-
)
|
|
550
|
-
httpx_mock.add_response(
|
|
551
|
-
url='http://lol/key?next_page=aoeu',
|
|
552
|
-
json=dict(total=2, items=[dict(a=2)]),
|
|
553
|
-
)
|
|
554
|
-
|
|
555
|
-
client = Client(base_url='http://lol')
|
|
556
|
-
items = []
|
|
557
|
-
async for item in client.Key.find():
|
|
558
|
-
items.append(item.data['a'])
|
|
559
|
-
assert items == [1, 2]
|
|
560
|
-
|
|
561
537
|
|
|
562
538
|
@pytest.mark.asyncio
|
|
563
539
|
async def test_pagination_reverse(httpx_mock):
|
|
564
540
|
httpx_mock.add_response(
|
|
565
|
-
url='http://lol/bar
|
|
541
|
+
url='http://lol/bar',
|
|
566
542
|
json=dict(total_pages=3, items=[dict(a=1), dict(a=2)]),
|
|
567
543
|
)
|
|
568
544
|
httpx_mock.add_response(
|
|
@@ -574,13 +550,13 @@ async def test_pagination_reverse(httpx_mock):
|
|
|
574
550
|
json=dict(total_pages=3, items=[dict(a=5)]),
|
|
575
551
|
)
|
|
576
552
|
|
|
553
|
+
class Paginator(cli2.Paginator):
|
|
554
|
+
def pagination_initialize(self, data):
|
|
555
|
+
self.total_pages = data['total_pages']
|
|
556
|
+
|
|
577
557
|
# test that we can reverse pagination too
|
|
578
558
|
class Client(cli2.Client):
|
|
579
|
-
|
|
580
|
-
paginator.total_pages = data['total_pages']
|
|
581
|
-
|
|
582
|
-
def pagination_parameters(self, paginator, page_number):
|
|
583
|
-
return dict(page=page_number)
|
|
559
|
+
paginator = Paginator
|
|
584
560
|
|
|
585
561
|
client = Client(base_url='http://lol')
|
|
586
562
|
paginator = client.paginate('/bar')
|
|
@@ -706,17 +682,18 @@ def test_relation_many():
|
|
|
706
682
|
|
|
707
683
|
@pytest.mark.asyncio
|
|
708
684
|
async def test_python_expression(httpx_mock):
|
|
685
|
+
class Paginator(cli2.Paginator):
|
|
686
|
+
def pagination_initialize(self, data):
|
|
687
|
+
self.total_pages = data['total_pages']
|
|
688
|
+
|
|
709
689
|
class Model(Client.Model):
|
|
710
690
|
url_list = '/foo'
|
|
711
691
|
a = cli2.Field()
|
|
712
692
|
b = cli2.Field()
|
|
713
|
-
|
|
714
|
-
@classmethod
|
|
715
|
-
def pagination_initialize(cls, paginator, data):
|
|
716
|
-
paginator.total_pages = data['total_pages']
|
|
693
|
+
paginator = Paginator
|
|
717
694
|
|
|
718
695
|
def mock():
|
|
719
|
-
httpx_mock.add_response(url='http://lol/foo
|
|
696
|
+
httpx_mock.add_response(url='http://lol/foo', json=dict(
|
|
720
697
|
total_pages=2,
|
|
721
698
|
items=[dict(a=1, b=1), dict(a=2, b=2), dict(a=3, b=1)],
|
|
722
699
|
))
|
|
@@ -766,7 +743,7 @@ async def test_expression_parameter(httpx_mock):
|
|
|
766
743
|
a = cli2.Field()
|
|
767
744
|
b = cli2.Field(parameter='b')
|
|
768
745
|
|
|
769
|
-
httpx_mock.add_response(url='http://lol/foo?
|
|
746
|
+
httpx_mock.add_response(url='http://lol/foo?b=1', json=dict(
|
|
770
747
|
items=[dict(a=1, b=1), dict(a=3, b=1)],
|
|
771
748
|
))
|
|
772
749
|
httpx_mock.add_response(url='http://lol/foo?page=2&b=1', json=dict())
|
|
@@ -812,7 +789,7 @@ async def test_client_cli2(httpx_mock):
|
|
|
812
789
|
|
|
813
790
|
meth = Client.cli['foo']['find']
|
|
814
791
|
httpx_mock.add_response(
|
|
815
|
-
url='http://lol/foo
|
|
792
|
+
url='http://lol/foo',
|
|
816
793
|
json=[dict(id=1, a=2)],
|
|
817
794
|
)
|
|
818
795
|
httpx_mock.add_response(url='http://lol/foo?page=2', json=[])
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.2
|
|
2
2
|
Name: cli2
|
|
3
|
-
Version: 3.3.
|
|
3
|
+
Version: 3.3.41
|
|
4
4
|
Summary: image:: https://yourlabs.io/oss/cli2/badges/master/pipeline.svg
|
|
5
5
|
Home-page: https://yourlabs.io/oss/cli2
|
|
6
6
|
Author: James Pic
|
|
@@ -23,6 +23,17 @@ Requires-Dist: pytest-cov; extra == "test"
|
|
|
23
23
|
Requires-Dist: pytest-mock; extra == "test"
|
|
24
24
|
Requires-Dist: pytest-asyncio; extra == "test"
|
|
25
25
|
Requires-Dist: pytest-httpx; extra == "test"
|
|
26
|
+
Dynamic: author
|
|
27
|
+
Dynamic: author-email
|
|
28
|
+
Dynamic: description
|
|
29
|
+
Dynamic: description-content-type
|
|
30
|
+
Dynamic: home-page
|
|
31
|
+
Dynamic: keywords
|
|
32
|
+
Dynamic: license
|
|
33
|
+
Dynamic: provides-extra
|
|
34
|
+
Dynamic: requires-dist
|
|
35
|
+
Dynamic: requires-python
|
|
36
|
+
Dynamic: summary
|
|
26
37
|
|
|
27
38
|
.. image:: https://yourlabs.io/oss/cli2/badges/master/pipeline.svg
|
|
28
39
|
:target: https://yourlabs.io/oss/cli2/pipelines
|
|
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
|