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.
- {cli2-4.0.6/cli2.egg-info → cli2-4.0.8}/PKG-INFO +1 -1
- {cli2-4.0.6 → cli2-4.0.8}/cli2/client.py +40 -17
- {cli2-4.0.6 → cli2-4.0.8/cli2.egg-info}/PKG-INFO +1 -1
- {cli2-4.0.6 → cli2-4.0.8}/setup.py +1 -1
- {cli2-4.0.6 → cli2-4.0.8}/tests/test_client.py +24 -21
- {cli2-4.0.6 → cli2-4.0.8}/MANIFEST.in +0 -0
- {cli2-4.0.6 → cli2-4.0.8}/README.rst +0 -0
- {cli2-4.0.6 → cli2-4.0.8}/classifiers.txt +0 -0
- {cli2-4.0.6 → cli2-4.0.8}/cli2/__init__.py +0 -0
- {cli2-4.0.6 → cli2-4.0.8}/cli2/ansible/__init__.py +0 -0
- {cli2-4.0.6 → cli2-4.0.8}/cli2/ansible/action.py +0 -0
- {cli2-4.0.6 → cli2-4.0.8}/cli2/ansible/playbook.py +0 -0
- {cli2-4.0.6 → cli2-4.0.8}/cli2/ansible/pytest.py +0 -0
- {cli2-4.0.6 → cli2-4.0.8}/cli2/ansible/variables.py +0 -0
- {cli2-4.0.6 → cli2-4.0.8}/cli2/asyncio.py +0 -0
- {cli2-4.0.6 → cli2-4.0.8}/cli2/cli.py +0 -0
- {cli2-4.0.6 → cli2-4.0.8}/cli2/cli2.py +0 -0
- {cli2-4.0.6 → cli2-4.0.8}/cli2/colors.py +0 -0
- {cli2-4.0.6 → cli2-4.0.8}/cli2/configuration.py +0 -0
- {cli2-4.0.6 → cli2-4.0.8}/cli2/decorators.py +0 -0
- {cli2-4.0.6 → cli2-4.0.8}/cli2/display.py +0 -0
- {cli2-4.0.6 → cli2-4.0.8}/cli2/examples/__init__.py +0 -0
- {cli2-4.0.6 → cli2-4.0.8}/cli2/examples/client.py +0 -0
- {cli2-4.0.6 → cli2-4.0.8}/cli2/examples/conf.py +0 -0
- {cli2-4.0.6 → cli2-4.0.8}/cli2/examples/example.py +0 -0
- {cli2-4.0.6 → cli2-4.0.8}/cli2/examples/example_obj.py +0 -0
- {cli2-4.0.6 → cli2-4.0.8}/cli2/examples/nesting.py +0 -0
- {cli2-4.0.6 → cli2-4.0.8}/cli2/examples/obj.py +0 -0
- {cli2-4.0.6 → cli2-4.0.8}/cli2/examples/obj2.py +0 -0
- {cli2-4.0.6 → cli2-4.0.8}/cli2/examples/test.py +0 -0
- {cli2-4.0.6 → cli2-4.0.8}/cli2/lock.py +0 -0
- {cli2-4.0.6 → cli2-4.0.8}/cli2/log.py +0 -0
- {cli2-4.0.6 → cli2-4.0.8}/cli2/node.py +0 -0
- {cli2-4.0.6 → cli2-4.0.8}/cli2/sphinx.py +0 -0
- {cli2-4.0.6 → cli2-4.0.8}/cli2/table.py +0 -0
- {cli2-4.0.6 → cli2-4.0.8}/cli2/test.py +0 -0
- {cli2-4.0.6 → cli2-4.0.8}/cli2.egg-info/SOURCES.txt +0 -0
- {cli2-4.0.6 → cli2-4.0.8}/cli2.egg-info/dependency_links.txt +0 -0
- {cli2-4.0.6 → cli2-4.0.8}/cli2.egg-info/entry_points.txt +0 -0
- {cli2-4.0.6 → cli2-4.0.8}/cli2.egg-info/requires.txt +0 -0
- {cli2-4.0.6 → cli2-4.0.8}/cli2.egg-info/top_level.txt +0 -0
- {cli2-4.0.6 → cli2-4.0.8}/setup.cfg +0 -0
- {cli2-4.0.6 → cli2-4.0.8}/tests/test_ansible.py +0 -0
- {cli2-4.0.6 → cli2-4.0.8}/tests/test_ansible_variables.py +0 -0
- {cli2-4.0.6 → cli2-4.0.8}/tests/test_cli.py +0 -0
- {cli2-4.0.6 → cli2-4.0.8}/tests/test_command.py +0 -0
- {cli2-4.0.6 → cli2-4.0.8}/tests/test_configuration.py +0 -0
- {cli2-4.0.6 → cli2-4.0.8}/tests/test_decorators.py +0 -0
- {cli2-4.0.6 → cli2-4.0.8}/tests/test_display.py +0 -0
- {cli2-4.0.6 → cli2-4.0.8}/tests/test_entry_point.py +0 -0
- {cli2-4.0.6 → cli2-4.0.8}/tests/test_group.py +0 -0
- {cli2-4.0.6 → cli2-4.0.8}/tests/test_inject.py +0 -0
- {cli2-4.0.6 → cli2-4.0.8}/tests/test_lock.py +0 -0
- {cli2-4.0.6 → cli2-4.0.8}/tests/test_node.py +0 -0
- {cli2-4.0.6 → cli2-4.0.8}/tests/test_restful.py +0 -0
- {cli2-4.0.6 → cli2-4.0.8}/tests/test_table.py +0 -0
|
@@ -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
|
|
@@ -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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|