cli2 4.0.6__tar.gz → 4.0.8__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.
Files changed (56) hide show
  1. {cli2-4.0.6/cli2.egg-info → cli2-4.0.8}/PKG-INFO +1 -1
  2. {cli2-4.0.6 → cli2-4.0.8}/cli2/client.py +40 -17
  3. {cli2-4.0.6 → cli2-4.0.8/cli2.egg-info}/PKG-INFO +1 -1
  4. {cli2-4.0.6 → cli2-4.0.8}/setup.py +1 -1
  5. {cli2-4.0.6 → cli2-4.0.8}/tests/test_client.py +24 -21
  6. {cli2-4.0.6 → cli2-4.0.8}/MANIFEST.in +0 -0
  7. {cli2-4.0.6 → cli2-4.0.8}/README.rst +0 -0
  8. {cli2-4.0.6 → cli2-4.0.8}/classifiers.txt +0 -0
  9. {cli2-4.0.6 → cli2-4.0.8}/cli2/__init__.py +0 -0
  10. {cli2-4.0.6 → cli2-4.0.8}/cli2/ansible/__init__.py +0 -0
  11. {cli2-4.0.6 → cli2-4.0.8}/cli2/ansible/action.py +0 -0
  12. {cli2-4.0.6 → cli2-4.0.8}/cli2/ansible/playbook.py +0 -0
  13. {cli2-4.0.6 → cli2-4.0.8}/cli2/ansible/pytest.py +0 -0
  14. {cli2-4.0.6 → cli2-4.0.8}/cli2/ansible/variables.py +0 -0
  15. {cli2-4.0.6 → cli2-4.0.8}/cli2/asyncio.py +0 -0
  16. {cli2-4.0.6 → cli2-4.0.8}/cli2/cli.py +0 -0
  17. {cli2-4.0.6 → cli2-4.0.8}/cli2/cli2.py +0 -0
  18. {cli2-4.0.6 → cli2-4.0.8}/cli2/colors.py +0 -0
  19. {cli2-4.0.6 → cli2-4.0.8}/cli2/configuration.py +0 -0
  20. {cli2-4.0.6 → cli2-4.0.8}/cli2/decorators.py +0 -0
  21. {cli2-4.0.6 → cli2-4.0.8}/cli2/display.py +0 -0
  22. {cli2-4.0.6 → cli2-4.0.8}/cli2/examples/__init__.py +0 -0
  23. {cli2-4.0.6 → cli2-4.0.8}/cli2/examples/client.py +0 -0
  24. {cli2-4.0.6 → cli2-4.0.8}/cli2/examples/conf.py +0 -0
  25. {cli2-4.0.6 → cli2-4.0.8}/cli2/examples/example.py +0 -0
  26. {cli2-4.0.6 → cli2-4.0.8}/cli2/examples/example_obj.py +0 -0
  27. {cli2-4.0.6 → cli2-4.0.8}/cli2/examples/nesting.py +0 -0
  28. {cli2-4.0.6 → cli2-4.0.8}/cli2/examples/obj.py +0 -0
  29. {cli2-4.0.6 → cli2-4.0.8}/cli2/examples/obj2.py +0 -0
  30. {cli2-4.0.6 → cli2-4.0.8}/cli2/examples/test.py +0 -0
  31. {cli2-4.0.6 → cli2-4.0.8}/cli2/lock.py +0 -0
  32. {cli2-4.0.6 → cli2-4.0.8}/cli2/log.py +0 -0
  33. {cli2-4.0.6 → cli2-4.0.8}/cli2/node.py +0 -0
  34. {cli2-4.0.6 → cli2-4.0.8}/cli2/sphinx.py +0 -0
  35. {cli2-4.0.6 → cli2-4.0.8}/cli2/table.py +0 -0
  36. {cli2-4.0.6 → cli2-4.0.8}/cli2/test.py +0 -0
  37. {cli2-4.0.6 → cli2-4.0.8}/cli2.egg-info/SOURCES.txt +0 -0
  38. {cli2-4.0.6 → cli2-4.0.8}/cli2.egg-info/dependency_links.txt +0 -0
  39. {cli2-4.0.6 → cli2-4.0.8}/cli2.egg-info/entry_points.txt +0 -0
  40. {cli2-4.0.6 → cli2-4.0.8}/cli2.egg-info/requires.txt +0 -0
  41. {cli2-4.0.6 → cli2-4.0.8}/cli2.egg-info/top_level.txt +0 -0
  42. {cli2-4.0.6 → cli2-4.0.8}/setup.cfg +0 -0
  43. {cli2-4.0.6 → cli2-4.0.8}/tests/test_ansible.py +0 -0
  44. {cli2-4.0.6 → cli2-4.0.8}/tests/test_ansible_variables.py +0 -0
  45. {cli2-4.0.6 → cli2-4.0.8}/tests/test_cli.py +0 -0
  46. {cli2-4.0.6 → cli2-4.0.8}/tests/test_command.py +0 -0
  47. {cli2-4.0.6 → cli2-4.0.8}/tests/test_configuration.py +0 -0
  48. {cli2-4.0.6 → cli2-4.0.8}/tests/test_decorators.py +0 -0
  49. {cli2-4.0.6 → cli2-4.0.8}/tests/test_display.py +0 -0
  50. {cli2-4.0.6 → cli2-4.0.8}/tests/test_entry_point.py +0 -0
  51. {cli2-4.0.6 → cli2-4.0.8}/tests/test_group.py +0 -0
  52. {cli2-4.0.6 → cli2-4.0.8}/tests/test_inject.py +0 -0
  53. {cli2-4.0.6 → cli2-4.0.8}/tests/test_lock.py +0 -0
  54. {cli2-4.0.6 → cli2-4.0.8}/tests/test_node.py +0 -0
  55. {cli2-4.0.6 → cli2-4.0.8}/tests/test_restful.py +0 -0
  56. {cli2-4.0.6 → cli2-4.0.8}/tests/test_table.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: cli2
3
- Version: 4.0.6
3
+ Version: 4.0.8
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
@@ -690,6 +690,7 @@ class ModelMetaclass(type):
690
690
  def __new__(cls, name, bases, attributes):
691
691
  if 'Paginator' in attributes:
692
692
  attributes['paginator'] = attributes['Paginator']
693
+
693
694
  cls = super().__new__(cls, name, bases, attributes)
694
695
  client = getattr(cls, 'client', None)
695
696
  if client:
@@ -700,11 +701,6 @@ class ModelMetaclass(type):
700
701
  client_class = getattr(cls, '_client_class', None)
701
702
  if client_class:
702
703
  client_class.models.append(cls)
703
- client_cli = getattr(client_class, 'cli', None)
704
- if client_cli:
705
- group = ModelGroup(cls)
706
- if len(group) > 1:
707
- cls.cli = client_cli[cls.__name__.lower()] = group
708
704
 
709
705
  cls._fields = dict()
710
706
 
@@ -939,6 +935,8 @@ class Model(metaclass=ModelMetaclass):
939
935
 
940
936
 
941
937
  class ClientMetaclass(type):
938
+ cli_kwargs = dict()
939
+
942
940
  def __new__(cls, name, bases, attributes):
943
941
  if 'Paginator' in attributes:
944
942
  attributes['paginator'] = attributes['Paginator']
@@ -947,20 +945,29 @@ class ClientMetaclass(type):
947
945
  # bind ourself as _client_class to any inherited model
948
946
  cls.Model = type('Model', (Model,), dict(_client_class=cls))
949
947
  cls.models = []
950
-
951
- cli_kwargs = dict(
952
- name=cls.__name__.lower().replace('client', '') or 'client',
953
- doc=inspect.getdoc(cls),
954
- overrides=dict(
955
- cls=dict(factory=lambda: cls),
956
- self=dict(factory=lambda: cls())
957
- ),
958
- )
959
- cli_kwargs.update(cls.__dict__.get('cli_kwargs', dict()))
960
- cls.cli = Group(**cli_kwargs)
961
- cls.cli.load(cls)
962
948
  return cls
963
949
 
950
+ @property
951
+ def cli(cls):
952
+ if '_cli' not in cls.__dict__:
953
+ cli_kwargs = dict(
954
+ name=cls.__name__.lower().replace('client', '') or 'client',
955
+ doc=inspect.getdoc(cls),
956
+ overrides=dict(
957
+ cls=dict(factory=lambda: cls),
958
+ self=dict(factory=lambda: cls())
959
+ ),
960
+ )
961
+ cli_kwargs.update(cls.cli_kwargs)
962
+ cli = Group(**cli_kwargs)
963
+ cli.load(cls)
964
+ for model in cls.models:
965
+ group = ModelGroup(model)
966
+ if len(group) > 1:
967
+ cli[model.__name__.lower()] = group
968
+ cls._cli = cli
969
+ return cls._cli
970
+
964
971
 
965
972
  class Handler:
966
973
  """
@@ -1204,6 +1211,22 @@ class Client(metaclass=ClientMetaclass):
1204
1211
 
1205
1212
  List of keys to mask in logging, ie.: ``['password', 'secret']``
1206
1213
 
1214
+ .. py:attribute:: cli
1215
+
1216
+ Generated :py:class:`~cli2.cli.Group` for this client.
1217
+ Uses :py:attr:`cli_kwargs` to pass kwargs to the generated group.
1218
+ Note that this is a cached property.
1219
+
1220
+ .. py:attribute:: cli_kwargs
1221
+
1222
+ Dict of overrides for the generated :py:class:`~cli2.cli.Group`.
1223
+ Example:
1224
+
1225
+ .. code-block:: python
1226
+
1227
+ class YourClient(cli2.Client):
1228
+ cli_kwargs = dict(cmdclass=YourCommandClass)
1229
+
1207
1230
  .. py:attribute:: debug
1208
1231
 
1209
1232
  Enforce full logging: quiet requests are logged, masking does not
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: cli2
3
- Version: 4.0.6
3
+ Version: 4.0.8
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
@@ -3,7 +3,7 @@ from setuptools import setup
3
3
 
4
4
  setup(
5
5
  name='cli2',
6
- version='4.0.6',
6
+ version='4.0.8',
7
7
  setup_requires='setupmeta',
8
8
  install_requires=[
9
9
  'docstring_parser',
@@ -37,6 +37,17 @@ def client_class():
37
37
 
38
38
  @pytest.mark.asyncio
39
39
  async def test_client_cli(client_class, httpx_mock):
40
+ class TestModel(client_class.Model):
41
+ url_list = '/'
42
+
43
+ class TestModel2(client_class.Model):
44
+ pass
45
+
46
+ class TestModel3(client_class.Model):
47
+ @cli2.cmd
48
+ def find():
49
+ pass
50
+
40
51
  assert client_class.cli
41
52
  factory = client_class.cli.overrides['self']['factory']
42
53
  assert isinstance(factory(), client_class)
@@ -45,8 +56,6 @@ async def test_client_cli(client_class, httpx_mock):
45
56
  response = await client_class.cli['get'].async_call('http://lol')
46
57
  assert response.json() == [1]
47
58
 
48
- class TestModel(client_class.Model):
49
- url_list = '/'
50
59
  assert 'testmodel' in client_class.cli
51
60
  assert client_class.cli['testmodel']['get'].overrides['cls']['factory']
52
61
  assert not inspect.ismethod(client_class.cli['testmodel']['get'].target)
@@ -58,16 +67,8 @@ async def test_client_cli(client_class, httpx_mock):
58
67
  httpx_mock.add_response(url='http://lol/?page=2', json=[])
59
68
  await client_class.cli['testmodel']['find'].async_call()
60
69
 
61
- class TestModel2(client_class.Model):
62
- pass
63
-
64
70
  assert 'testmodel2' not in client_class.cli
65
71
 
66
- class TestModel3(client_class.Model):
67
- @cli2.cmd
68
- def find():
69
- pass
70
-
71
72
  assert list(client_class.cli['testmodel3'].keys()) == ['help', 'find']
72
73
 
73
74
 
@@ -85,7 +86,6 @@ async def test_client_cli_override(client_class, httpx_mock):
85
86
  @cli2.cmd
86
87
  async def find(cls, foo):
87
88
  return cls.url_list
88
- assert await Client.cli['testmodel']['find'].async_call('bar') == 'bar/foo'
89
89
 
90
90
  class TestModel2(Client.Model):
91
91
  @classmethod
@@ -93,12 +93,15 @@ async def test_client_cli_override(client_class, httpx_mock):
93
93
  async def find(cls):
94
94
  return 'foo'
95
95
 
96
- assert await Client.cli['testmodel2']['find'].async_call() == 'foo'
97
- assert 'get' not in Client.cli['testmodel2']
98
-
99
96
  class TestModel3(Client.Model):
100
97
  url_list = '{client.test}/foo'
101
98
  create = None
99
+
100
+ assert await Client.cli['testmodel']['find'].async_call('bar') == 'bar/foo'
101
+
102
+ assert await Client.cli['testmodel2']['find'].async_call() == 'foo'
103
+ assert 'get' not in Client.cli['testmodel2']
104
+
102
105
  assert 'create' not in Client.cli['testmodel3']
103
106
 
104
107
 
@@ -123,13 +126,13 @@ async def test_async_factory(httpx_mock, client_class):
123
126
  async def factory(cls):
124
127
  return cls(base_url='http://bar')
125
128
 
129
+ class TestModel(TestClient.Model):
130
+ url_list = '/2'
131
+
126
132
  TestClient.cli.overrides['self']['factory'] = TestClient.factory
127
133
  httpx_mock.add_response(url='http://bar/', json=[dict(a=1)])
128
134
  assert await TestClient.cli['get'].async_call('/')
129
135
 
130
- class TestModel(TestClient.Model):
131
- url_list = '/2'
132
-
133
136
  httpx_mock.add_response(url='http://bar/2', json=[dict(a=1)])
134
137
  httpx_mock.add_response(url='http://bar/2?page=2', json=[])
135
138
  await TestClient.cli['testmodel']['find'].async_call()
@@ -777,6 +780,10 @@ async def test_model_crud(httpx_mock, client_class):
777
780
 
778
781
  @pytest.mark.asyncio
779
782
  async def test_client_cli2(httpx_mock, client_class):
783
+ class Foo(client_class.Model):
784
+ id = cli2.Field()
785
+ url_list = '/foo'
786
+
780
787
  assert client_class.cli.name == 'test'
781
788
  assert client_class.cli.doc == 'doc'
782
789
 
@@ -785,10 +792,6 @@ async def test_client_cli2(httpx_mock, client_class):
785
792
  resp = await meth.async_call('/foo')
786
793
  assert resp.json() == [1]
787
794
 
788
- class Foo(client_class.Model):
789
- id = cli2.Field()
790
- url_list = '/foo'
791
-
792
795
  meth = client_class.cli['foo']['get']
793
796
  httpx_mock.add_response(url='http://lol/foo/1', json=dict(id=1, a=2))
794
797
  result = await meth.async_call('id=1')
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
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes