cli2 3.3.37__tar.gz → 3.3.40__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.40}/PKG-INFO +13 -2
- {cli2-3.3.37 → cli2-3.3.40}/cli2/client.py +26 -88
- {cli2-3.3.37 → cli2-3.3.40}/cli2/test_client.py +54 -76
- {cli2-3.3.37 → cli2-3.3.40/cli2.egg-info}/PKG-INFO +13 -2
- {cli2-3.3.37 → cli2-3.3.40}/setup.py +1 -1
- {cli2-3.3.37 → cli2-3.3.40}/MANIFEST.in +0 -0
- {cli2-3.3.37 → cli2-3.3.40}/README.rst +0 -0
- {cli2-3.3.37 → cli2-3.3.40}/classifiers.txt +0 -0
- {cli2-3.3.37 → cli2-3.3.40}/cli2/__init__.py +0 -0
- {cli2-3.3.37 → cli2-3.3.40}/cli2/argument.py +0 -0
- {cli2-3.3.37 → cli2-3.3.40}/cli2/asyncio.py +0 -0
- {cli2-3.3.37 → cli2-3.3.40}/cli2/cli.py +0 -0
- {cli2-3.3.37 → cli2-3.3.40}/cli2/colors.py +0 -0
- {cli2-3.3.37 → cli2-3.3.40}/cli2/command.py +0 -0
- {cli2-3.3.37 → cli2-3.3.40}/cli2/configuration.py +0 -0
- {cli2-3.3.37 → cli2-3.3.40}/cli2/decorators.py +0 -0
- {cli2-3.3.37 → cli2-3.3.40}/cli2/display.py +0 -0
- {cli2-3.3.37 → cli2-3.3.40}/cli2/entry_point.py +0 -0
- {cli2-3.3.37 → cli2-3.3.40}/cli2/example_client.py +0 -0
- {cli2-3.3.37 → cli2-3.3.40}/cli2/example_client_complex.py +0 -0
- {cli2-3.3.37 → cli2-3.3.40}/cli2/example_nesting.py +0 -0
- {cli2-3.3.37 → cli2-3.3.40}/cli2/example_obj.py +0 -0
- {cli2-3.3.37 → cli2-3.3.40}/cli2/group.py +0 -0
- {cli2-3.3.37 → cli2-3.3.40}/cli2/logging.py +0 -0
- {cli2-3.3.37 → cli2-3.3.40}/cli2/node.py +0 -0
- {cli2-3.3.37 → cli2-3.3.40}/cli2/overrides.py +0 -0
- {cli2-3.3.37 → cli2-3.3.40}/cli2/sphinx.py +0 -0
- {cli2-3.3.37 → cli2-3.3.40}/cli2/table.py +0 -0
- {cli2-3.3.37 → cli2-3.3.40}/cli2/test.py +0 -0
- {cli2-3.3.37 → cli2-3.3.40}/cli2/test_cli.py +0 -0
- {cli2-3.3.37 → cli2-3.3.40}/cli2/test_command.py +0 -0
- {cli2-3.3.37 → cli2-3.3.40}/cli2/test_configuration.py +0 -0
- {cli2-3.3.37 → cli2-3.3.40}/cli2/test_decorators.py +0 -0
- {cli2-3.3.37 → cli2-3.3.40}/cli2/test_display.py +0 -0
- {cli2-3.3.37 → cli2-3.3.40}/cli2/test_entry_point.py +0 -0
- {cli2-3.3.37 → cli2-3.3.40}/cli2/test_group.py +0 -0
- {cli2-3.3.37 → cli2-3.3.40}/cli2/test_inject.py +0 -0
- {cli2-3.3.37 → cli2-3.3.40}/cli2/test_node.py +0 -0
- {cli2-3.3.37 → cli2-3.3.40}/cli2/test_table.py +0 -0
- {cli2-3.3.37 → cli2-3.3.40}/cli2.egg-info/SOURCES.txt +0 -0
- {cli2-3.3.37 → cli2-3.3.40}/cli2.egg-info/dependency_links.txt +0 -0
- {cli2-3.3.37 → cli2-3.3.40}/cli2.egg-info/entry_points.txt +0 -0
- {cli2-3.3.37 → cli2-3.3.40}/cli2.egg-info/requires.txt +0 -0
- {cli2-3.3.37 → cli2-3.3.40}/cli2.egg-info/top_level.txt +0 -0
- {cli2-3.3.37 → cli2-3.3.40}/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.40
|
|
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,15 @@ 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
|
-
Callback called for every item before filtering.
|
|
73
|
+
Callback called for every item before filtering by expressions.
|
|
74
|
+
This must return True or the item will be filtered *out* of yielded
|
|
75
|
+
results.
|
|
86
76
|
"""
|
|
87
77
|
|
|
88
78
|
def __init__(self, client, url, params=None, model=None, expressions=None,
|
|
89
|
-
|
|
79
|
+
callback=None):
|
|
90
80
|
"""
|
|
91
81
|
Initialize a paginator object with a client on a URL with parameters.
|
|
92
82
|
|
|
@@ -102,8 +92,7 @@ class Paginator:
|
|
|
102
92
|
self.page_start = 1
|
|
103
93
|
self.per_page = None
|
|
104
94
|
self.initialized = False
|
|
105
|
-
self.
|
|
106
|
-
self.postfilter = postfilter
|
|
95
|
+
self.callback = callback
|
|
107
96
|
self.expressions = []
|
|
108
97
|
for expression in (expressions or []):
|
|
109
98
|
if not isinstance(expression, Expression):
|
|
@@ -180,12 +169,6 @@ class Paginator:
|
|
|
180
169
|
|
|
181
170
|
:param data: Data of the first response
|
|
182
171
|
"""
|
|
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
172
|
|
|
190
173
|
def pagination_parameters(self, page_number):
|
|
191
174
|
"""
|
|
@@ -199,15 +182,12 @@ class Paginator:
|
|
|
199
182
|
|
|
200
183
|
.. code-block:: python
|
|
201
184
|
|
|
202
|
-
def pagination_parameters(self,
|
|
185
|
+
def pagination_parameters(self, page_number):
|
|
186
|
+
# this is the default implementation
|
|
203
187
|
return dict(page=page_number)
|
|
204
188
|
"""
|
|
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)
|
|
189
|
+
if page_number > 1:
|
|
190
|
+
return dict(page=page_number)
|
|
211
191
|
|
|
212
192
|
def response_items(self, response):
|
|
213
193
|
"""
|
|
@@ -277,16 +257,17 @@ class Paginator:
|
|
|
277
257
|
await self.initialize(response)
|
|
278
258
|
return response
|
|
279
259
|
|
|
280
|
-
async def __aiter__(self,
|
|
260
|
+
async def __aiter__(self, callback=None):
|
|
281
261
|
"""
|
|
282
262
|
Asynchronous iterator.
|
|
283
263
|
"""
|
|
284
|
-
|
|
285
|
-
postfilter = postfilter or self.postfilter
|
|
264
|
+
callback = callback or self.callback
|
|
286
265
|
|
|
287
266
|
if self._reverse and not self.total_pages:
|
|
288
267
|
first_page_response = await self.page_response(1)
|
|
289
268
|
page = self.total_pages
|
|
269
|
+
if not self.total_pages:
|
|
270
|
+
raise Exception('Reverse pagination without total_pages')
|
|
290
271
|
else:
|
|
291
272
|
page = self.page_start
|
|
292
273
|
|
|
@@ -294,11 +275,10 @@ class Paginator:
|
|
|
294
275
|
|
|
295
276
|
async def yielder(items):
|
|
296
277
|
for item in items:
|
|
297
|
-
if
|
|
298
|
-
await async_resolve(
|
|
278
|
+
if callback:
|
|
279
|
+
if not await async_resolve(callback(item)):
|
|
280
|
+
continue
|
|
299
281
|
if not python_filter or python_filter.matches(item):
|
|
300
|
-
if postfilter:
|
|
301
|
-
await async_resolve(postfilter(item))
|
|
302
282
|
yield item
|
|
303
283
|
|
|
304
284
|
while items := await self.page_items(page):
|
|
@@ -836,32 +816,6 @@ class Model(metaclass=ModelMetaclass):
|
|
|
836
816
|
"""
|
|
837
817
|
return cls.paginator(cls.client, url, params, cls, expressions)
|
|
838
818
|
|
|
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
819
|
@property
|
|
866
820
|
def cli2_display(self):
|
|
867
821
|
return self.data
|
|
@@ -1179,9 +1133,7 @@ class Client(metaclass=ClientMetaclass):
|
|
|
1179
1133
|
|
|
1180
1134
|
.. py:attribute:: paginator
|
|
1181
1135
|
|
|
1182
|
-
:py:class:`Paginator` class
|
|
1183
|
-
implement :py:meth:`pagination_initialize` and
|
|
1184
|
-
:py:meth:`pagination_parameters`.
|
|
1136
|
+
:py:class:`Paginator` class
|
|
1185
1137
|
|
|
1186
1138
|
.. py:attribute:: semaphore
|
|
1187
1139
|
|
|
@@ -1607,7 +1559,8 @@ class Client(metaclass=ClientMetaclass):
|
|
|
1607
1559
|
""" DELETE Request """
|
|
1608
1560
|
return await self.request('DELETE', url, *args, **kwargs)
|
|
1609
1561
|
|
|
1610
|
-
def paginate(self, url, params=None, model=None
|
|
1562
|
+
def paginate(self, url, *expressions, params=None, model=None,
|
|
1563
|
+
callback=None):
|
|
1611
1564
|
"""
|
|
1612
1565
|
Return a paginator to iterate over results
|
|
1613
1566
|
|
|
@@ -1615,23 +1568,8 @@ class Client(metaclass=ClientMetaclass):
|
|
|
1615
1568
|
:param params: GET parameters
|
|
1616
1569
|
:param model: Model class to cast for items
|
|
1617
1570
|
"""
|
|
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
|
-
"""
|
|
1571
|
+
return self.paginator(self, url, params or {}, model or dict,
|
|
1572
|
+
expressions, callback)
|
|
1635
1573
|
|
|
1636
1574
|
|
|
1637
1575
|
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,22 @@ 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
|
+
def callback(item):
|
|
379
380
|
item['b'] = item['a']
|
|
381
|
+
return True
|
|
380
382
|
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
383
|
+
paginator = client.paginate(
|
|
384
|
+
'/',
|
|
385
|
+
lambda item: item['b'] == 2,
|
|
386
|
+
callback=callback,
|
|
387
|
+
)
|
|
386
388
|
assert await paginator.list() == [
|
|
387
|
-
dict(a=
|
|
388
|
-
dict(a=2, b=2, c=2)
|
|
389
|
+
dict(a=2, b=2)
|
|
389
390
|
]
|
|
390
391
|
|
|
391
392
|
|
|
@@ -406,11 +407,12 @@ def test_paginator(client_class):
|
|
|
406
407
|
|
|
407
408
|
@pytest.mark.asyncio
|
|
408
409
|
async def test_pagination_initialize(httpx_mock):
|
|
409
|
-
httpx_mock.add_response(url='http://lol
|
|
410
|
+
httpx_mock.add_response(url='http://lol/', json=dict(
|
|
410
411
|
total_pages=2,
|
|
411
412
|
items=[dict(a=1)],
|
|
412
413
|
))
|
|
413
414
|
httpx_mock.add_response(url='http://lol/?page=2', json=[dict(a=2)])
|
|
415
|
+
httpx_mock.add_response(url='http://lol/?page=3', json=[])
|
|
414
416
|
|
|
415
417
|
class PaginatedClient(Client):
|
|
416
418
|
def pagination_initialize(self, paginator, data):
|
|
@@ -419,7 +421,7 @@ async def test_pagination_initialize(httpx_mock):
|
|
|
419
421
|
client = PaginatedClient(base_url='http://lol')
|
|
420
422
|
assert await client.paginate('/').list() == [dict(a=1), dict(a=2)]
|
|
421
423
|
|
|
422
|
-
httpx_mock.add_response(url='http://lol
|
|
424
|
+
httpx_mock.add_response(url='http://lol/', json=dict(
|
|
423
425
|
total_pages=2,
|
|
424
426
|
items=[dict(a=1)],
|
|
425
427
|
))
|
|
@@ -429,7 +431,7 @@ async def test_pagination_initialize(httpx_mock):
|
|
|
429
431
|
@pytest.mark.asyncio
|
|
430
432
|
async def test_token_get(httpx_mock):
|
|
431
433
|
httpx_mock.add_response(url='http://lol/token', json=dict(token=123))
|
|
432
|
-
httpx_mock.add_response(url='http://lol
|
|
434
|
+
httpx_mock.add_response(url='http://lol/', json=[])
|
|
433
435
|
|
|
434
436
|
class TokenClient(Client):
|
|
435
437
|
async def token_get(self):
|
|
@@ -446,7 +448,7 @@ async def test_pagination_model(httpx_mock):
|
|
|
446
448
|
class Model(dict):
|
|
447
449
|
pass
|
|
448
450
|
|
|
449
|
-
httpx_mock.add_response(url='http://lol
|
|
451
|
+
httpx_mock.add_response(url='http://lol/', json=[dict(a=2)])
|
|
450
452
|
httpx_mock.add_response(url='http://lol/?page=2', json=[])
|
|
451
453
|
client = Client(base_url='http://lol')
|
|
452
454
|
result = await client.paginate('/', model=Model).list()
|
|
@@ -465,47 +467,50 @@ async def test_pagination_patterns(httpx_mock):
|
|
|
465
467
|
# I'm dealing with APIs which have a different pagination system on
|
|
466
468
|
# different resources, and on some resources no pagination at all
|
|
467
469
|
# Would like to define that per model
|
|
470
|
+
|
|
471
|
+
class TotalPaginator(cli2.Paginator):
|
|
472
|
+
def pagination_initialize(self, data):
|
|
473
|
+
self.total_items = data['total_items']
|
|
474
|
+
self.per_page = len(data['items'])
|
|
475
|
+
|
|
468
476
|
class TotalModel(Client.Model):
|
|
477
|
+
paginator = TotalPaginator
|
|
469
478
|
url_list = '/foo'
|
|
470
479
|
|
|
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
480
|
httpx_mock.add_response(
|
|
477
|
-
url='http://lol/foo
|
|
481
|
+
url='http://lol/foo',
|
|
478
482
|
json=dict(total_items=2, items=[dict(a=1)]),
|
|
479
483
|
)
|
|
480
484
|
|
|
485
|
+
class PagesPaginator(cli2.Paginator):
|
|
486
|
+
def pagination_initialize(self, data):
|
|
487
|
+
self.total_pages = data['total_pages']
|
|
488
|
+
self.per_page = len(data['items'])
|
|
489
|
+
|
|
481
490
|
class Pages(Client.Model):
|
|
482
491
|
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'])
|
|
492
|
+
paginator = PagesPaginator
|
|
488
493
|
|
|
489
494
|
httpx_mock.add_response(
|
|
490
|
-
url='http://lol/bar
|
|
495
|
+
url='http://lol/bar',
|
|
491
496
|
json=dict(total_pages=1, items=[dict(a=1)]),
|
|
492
497
|
)
|
|
493
498
|
|
|
494
|
-
class
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
@classmethod
|
|
498
|
-
def pagination_initialize(cls, paginator, data):
|
|
499
|
-
paginator.total_items = data['total']
|
|
499
|
+
class OffsetPaginator(cli2.Paginator):
|
|
500
|
+
def pagination_initialize(self, data):
|
|
501
|
+
self.total_items = data['total']
|
|
500
502
|
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
paginator.per_page = 1
|
|
503
|
+
def pagination_parameters(self, page_number):
|
|
504
|
+
self.per_page = 1
|
|
504
505
|
return dict(
|
|
505
506
|
offset=(page_number - 1) * paginator.per_page,
|
|
506
507
|
limit=paginator.per_page,
|
|
507
508
|
)
|
|
508
509
|
|
|
510
|
+
class Offset(Client.Model):
|
|
511
|
+
url_list = '/off'
|
|
512
|
+
paginator = OffsetPaginator
|
|
513
|
+
|
|
509
514
|
httpx_mock.add_response(
|
|
510
515
|
url='http://lol/off?offset=0&limit=1',
|
|
511
516
|
json=dict(total=2, items=[dict(a=1)]),
|
|
@@ -530,39 +535,11 @@ async def test_pagination_patterns(httpx_mock):
|
|
|
530
535
|
assert paginator.per_page == 1
|
|
531
536
|
assert paginator.pagination_parameters(2) == dict(offset=1, limit=1)
|
|
532
537
|
|
|
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
538
|
|
|
562
539
|
@pytest.mark.asyncio
|
|
563
540
|
async def test_pagination_reverse(httpx_mock):
|
|
564
541
|
httpx_mock.add_response(
|
|
565
|
-
url='http://lol/bar
|
|
542
|
+
url='http://lol/bar',
|
|
566
543
|
json=dict(total_pages=3, items=[dict(a=1), dict(a=2)]),
|
|
567
544
|
)
|
|
568
545
|
httpx_mock.add_response(
|
|
@@ -574,13 +551,13 @@ async def test_pagination_reverse(httpx_mock):
|
|
|
574
551
|
json=dict(total_pages=3, items=[dict(a=5)]),
|
|
575
552
|
)
|
|
576
553
|
|
|
554
|
+
class Paginator(cli2.Paginator):
|
|
555
|
+
def pagination_initialize(self, data):
|
|
556
|
+
self.total_pages = data['total_pages']
|
|
557
|
+
|
|
577
558
|
# test that we can reverse pagination too
|
|
578
559
|
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)
|
|
560
|
+
paginator = Paginator
|
|
584
561
|
|
|
585
562
|
client = Client(base_url='http://lol')
|
|
586
563
|
paginator = client.paginate('/bar')
|
|
@@ -706,17 +683,18 @@ def test_relation_many():
|
|
|
706
683
|
|
|
707
684
|
@pytest.mark.asyncio
|
|
708
685
|
async def test_python_expression(httpx_mock):
|
|
686
|
+
class Paginator(cli2.Paginator):
|
|
687
|
+
def pagination_initialize(self, data):
|
|
688
|
+
self.total_pages = data['total_pages']
|
|
689
|
+
|
|
709
690
|
class Model(Client.Model):
|
|
710
691
|
url_list = '/foo'
|
|
711
692
|
a = cli2.Field()
|
|
712
693
|
b = cli2.Field()
|
|
713
|
-
|
|
714
|
-
@classmethod
|
|
715
|
-
def pagination_initialize(cls, paginator, data):
|
|
716
|
-
paginator.total_pages = data['total_pages']
|
|
694
|
+
paginator = Paginator
|
|
717
695
|
|
|
718
696
|
def mock():
|
|
719
|
-
httpx_mock.add_response(url='http://lol/foo
|
|
697
|
+
httpx_mock.add_response(url='http://lol/foo', json=dict(
|
|
720
698
|
total_pages=2,
|
|
721
699
|
items=[dict(a=1, b=1), dict(a=2, b=2), dict(a=3, b=1)],
|
|
722
700
|
))
|
|
@@ -766,7 +744,7 @@ async def test_expression_parameter(httpx_mock):
|
|
|
766
744
|
a = cli2.Field()
|
|
767
745
|
b = cli2.Field(parameter='b')
|
|
768
746
|
|
|
769
|
-
httpx_mock.add_response(url='http://lol/foo?
|
|
747
|
+
httpx_mock.add_response(url='http://lol/foo?b=1', json=dict(
|
|
770
748
|
items=[dict(a=1, b=1), dict(a=3, b=1)],
|
|
771
749
|
))
|
|
772
750
|
httpx_mock.add_response(url='http://lol/foo?page=2&b=1', json=dict())
|
|
@@ -812,7 +790,7 @@ async def test_client_cli2(httpx_mock):
|
|
|
812
790
|
|
|
813
791
|
meth = Client.cli['foo']['find']
|
|
814
792
|
httpx_mock.add_response(
|
|
815
|
-
url='http://lol/foo
|
|
793
|
+
url='http://lol/foo',
|
|
816
794
|
json=[dict(id=1, a=2)],
|
|
817
795
|
)
|
|
818
796
|
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.40
|
|
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
|