moat-kv 0.70.23__py3-none-any.whl → 0.70.24__py3-none-any.whl

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 (125) hide show
  1. build/lib/docs/source/conf.py +201 -0
  2. build/lib/examples/pathify.py +45 -0
  3. build/lib/moat/kv/__init__.py +19 -0
  4. build/lib/moat/kv/_cfg.yaml +97 -0
  5. build/lib/moat/kv/_main.py +91 -0
  6. build/lib/moat/kv/actor/__init__.py +98 -0
  7. build/lib/moat/kv/actor/deletor.py +139 -0
  8. build/lib/moat/kv/auth/__init__.py +444 -0
  9. build/lib/moat/kv/auth/_test.py +166 -0
  10. build/lib/moat/kv/auth/password.py +234 -0
  11. build/lib/moat/kv/auth/root.py +58 -0
  12. build/lib/moat/kv/backend/__init__.py +67 -0
  13. build/lib/moat/kv/backend/mqtt.py +74 -0
  14. build/lib/moat/kv/backend/serf.py +45 -0
  15. build/lib/moat/kv/client.py +1025 -0
  16. build/lib/moat/kv/code.py +236 -0
  17. build/lib/moat/kv/codec.py +11 -0
  18. build/lib/moat/kv/command/__init__.py +1 -0
  19. build/lib/moat/kv/command/acl.py +180 -0
  20. build/lib/moat/kv/command/auth.py +261 -0
  21. build/lib/moat/kv/command/code.py +293 -0
  22. build/lib/moat/kv/command/codec.py +186 -0
  23. build/lib/moat/kv/command/data.py +265 -0
  24. build/lib/moat/kv/command/dump/__init__.py +143 -0
  25. build/lib/moat/kv/command/error.py +149 -0
  26. build/lib/moat/kv/command/internal.py +248 -0
  27. build/lib/moat/kv/command/job.py +433 -0
  28. build/lib/moat/kv/command/log.py +53 -0
  29. build/lib/moat/kv/command/server.py +114 -0
  30. build/lib/moat/kv/command/type.py +201 -0
  31. build/lib/moat/kv/config.py +46 -0
  32. build/lib/moat/kv/data.py +216 -0
  33. build/lib/moat/kv/errors.py +561 -0
  34. build/lib/moat/kv/exceptions.py +126 -0
  35. build/lib/moat/kv/mock/__init__.py +101 -0
  36. build/lib/moat/kv/mock/mqtt.py +159 -0
  37. build/lib/moat/kv/mock/serf.py +250 -0
  38. build/lib/moat/kv/mock/tracer.py +63 -0
  39. build/lib/moat/kv/model.py +1069 -0
  40. build/lib/moat/kv/obj/__init__.py +646 -0
  41. build/lib/moat/kv/obj/command.py +241 -0
  42. build/lib/moat/kv/runner.py +1347 -0
  43. build/lib/moat/kv/server.py +2809 -0
  44. build/lib/moat/kv/types.py +513 -0
  45. debian/moat-kv/usr/lib/python3/dist-packages/docs/source/conf.py +201 -0
  46. debian/moat-kv/usr/lib/python3/dist-packages/examples/pathify.py +45 -0
  47. debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/__init__.py +19 -0
  48. debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/_cfg.yaml +97 -0
  49. debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/_main.py +91 -0
  50. debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/actor/__init__.py +98 -0
  51. debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/actor/deletor.py +139 -0
  52. debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/auth/__init__.py +444 -0
  53. debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/auth/_test.py +166 -0
  54. debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/auth/password.py +234 -0
  55. debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/auth/root.py +58 -0
  56. debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/backend/__init__.py +67 -0
  57. debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/backend/mqtt.py +74 -0
  58. debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/backend/serf.py +45 -0
  59. debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/client.py +1025 -0
  60. debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/code.py +236 -0
  61. debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/codec.py +11 -0
  62. debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/command/__init__.py +1 -0
  63. debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/command/acl.py +180 -0
  64. debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/command/auth.py +261 -0
  65. debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/command/code.py +293 -0
  66. debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/command/codec.py +186 -0
  67. debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/command/data.py +265 -0
  68. debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/command/dump/__init__.py +143 -0
  69. debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/command/error.py +149 -0
  70. debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/command/internal.py +248 -0
  71. debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/command/job.py +433 -0
  72. debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/command/log.py +53 -0
  73. debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/command/server.py +114 -0
  74. debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/command/type.py +201 -0
  75. debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/config.py +46 -0
  76. debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/data.py +216 -0
  77. debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/errors.py +561 -0
  78. debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/exceptions.py +126 -0
  79. debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/mock/__init__.py +101 -0
  80. debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/mock/mqtt.py +159 -0
  81. debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/mock/serf.py +250 -0
  82. debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/mock/tracer.py +63 -0
  83. debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/model.py +1069 -0
  84. debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/obj/__init__.py +646 -0
  85. debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/obj/command.py +241 -0
  86. debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/runner.py +1347 -0
  87. debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/server.py +2809 -0
  88. debian/moat-kv/usr/lib/python3/dist-packages/moat/kv/types.py +513 -0
  89. docs/source/conf.py +201 -0
  90. examples/pathify.py +45 -0
  91. moat/kv/actor/__init__.py +98 -0
  92. moat/kv/actor/deletor.py +139 -0
  93. moat/kv/auth/__init__.py +444 -0
  94. moat/kv/auth/_test.py +166 -0
  95. moat/kv/auth/password.py +234 -0
  96. moat/kv/auth/root.py +58 -0
  97. moat/kv/backend/__init__.py +67 -0
  98. moat/kv/backend/mqtt.py +74 -0
  99. moat/kv/backend/serf.py +45 -0
  100. moat/kv/command/__init__.py +1 -0
  101. moat/kv/command/acl.py +180 -0
  102. moat/kv/command/auth.py +261 -0
  103. moat/kv/command/code.py +293 -0
  104. moat/kv/command/codec.py +186 -0
  105. moat/kv/command/data.py +265 -0
  106. moat/kv/command/dump/__init__.py +143 -0
  107. moat/kv/command/error.py +149 -0
  108. moat/kv/command/internal.py +248 -0
  109. moat/kv/command/job.py +433 -0
  110. moat/kv/command/log.py +53 -0
  111. moat/kv/command/server.py +114 -0
  112. moat/kv/command/type.py +201 -0
  113. moat/kv/mock/__init__.py +101 -0
  114. moat/kv/mock/mqtt.py +159 -0
  115. moat/kv/mock/serf.py +250 -0
  116. moat/kv/mock/tracer.py +63 -0
  117. moat/kv/obj/__init__.py +646 -0
  118. moat/kv/obj/command.py +241 -0
  119. {moat_kv-0.70.23.dist-info → moat_kv-0.70.24.dist-info}/METADATA +2 -2
  120. moat_kv-0.70.24.dist-info/RECORD +137 -0
  121. moat_kv-0.70.24.dist-info/top_level.txt +9 -0
  122. moat_kv-0.70.23.dist-info/RECORD +0 -19
  123. moat_kv-0.70.23.dist-info/top_level.txt +0 -1
  124. {moat_kv-0.70.23.dist-info → moat_kv-0.70.24.dist-info}/WHEEL +0 -0
  125. {moat_kv-0.70.23.dist-info → moat_kv-0.70.24.dist-info}/licenses/LICENSE.txt +0 -0
@@ -0,0 +1,241 @@
1
+ # command line interface helpers for objects
2
+ from __future__ import annotations
3
+
4
+ import logging
5
+ import sys
6
+
7
+ import asyncclick as click
8
+ from moat.util import NotGiven
9
+
10
+ logger = logging.getLogger(__name__)
11
+
12
+ __all__ = ["std_command"]
13
+
14
+
15
+ class _InvSub:
16
+ """
17
+ This class is a helper for "std_command".
18
+ """
19
+
20
+ def __init__(
21
+ self,
22
+ name,
23
+ id_name="name",
24
+ id_typ=str,
25
+ aux=(),
26
+ name_cb=None,
27
+ id_cb=None,
28
+ postproc=None,
29
+ apply=None,
30
+ short_help=None,
31
+ sub_base=None,
32
+ sub_name=None,
33
+ long_name=None,
34
+ prepare=None,
35
+ list_recursive=False,
36
+ ):
37
+ self.name = name
38
+ self.id_name = id_name
39
+ self.id_typ = id_typ
40
+ self.id_cb = id_cb or (lambda _c, _k, x: x)
41
+ self.apply = apply or (lambda _c, _t, _x: None)
42
+ self.name_cb = name_cb or (lambda _c, _k, x: x)
43
+ self.aux = aux
44
+ self.short_help = short_help
45
+ self.postproc = postproc or (lambda _c, _t, x: None)
46
+ self.long_name = long_name or name
47
+ self.sub_base = sub_base
48
+ self.prepare = prepare
49
+ self.list_recursive = list_recursive
50
+ if sub_name is NotGiven:
51
+ self.sub_name = None
52
+ else:
53
+ self.sub_name = sub_name or name
54
+
55
+ def id_arg(self, proc):
56
+ if self.id_name is None:
57
+ return proc
58
+ return click.argument(self.id_name, type=self.id_typ, callback=self.id_cb, nargs=1)(proc)
59
+
60
+ def apply_aux(self, proc):
61
+ for t in self.aux:
62
+ proc = t(proc)
63
+ return proc
64
+
65
+
66
+ def std_command(cli, *a, **kw):
67
+ """
68
+ This procedure builds the interface for an inventory-ish thing.
69
+
70
+ Usage::
71
+
72
+ @click.group(short_help="Manage computer inventory.")
73
+ @click.pass_obj
74
+ async def cli(obj):
75
+ "Inventorize your computers, networks, and their connections."
76
+ obj.inv = await InventoryRoot.as_handler(obj.client)
77
+
78
+ std_command(
79
+ cli, # from above
80
+ "vlan", # subcommand name
81
+ "id", # item identifier
82
+ int, # item identifier type
83
+ aux=( # additional attributes
84
+ click.option("-d", "--desc", type=str, default=None, help="Description"),
85
+ click.option("-w", "--wlan", type=str, default=None, help="WLAN SSID"),
86
+ ),
87
+ short_help="Manage VLANs",
88
+ )
89
+ """
90
+ tinv = _InvSub(*a, **kw)
91
+ tname = tinv.name
92
+ tnname = "n_" + tname
93
+
94
+ def this(obj):
95
+ # Delayed resolving of the actual thing subhierarchy
96
+ if tinv.sub_base:
97
+ data = getattr(obj, tinv.sub_base)
98
+ else:
99
+ data = obj.data
100
+ if tinv.sub_name:
101
+ return getattr(data, tinv.sub_name)
102
+ return data
103
+
104
+ @cli.group(
105
+ name=tname,
106
+ invoke_without_command=True,
107
+ short_help=tinv.short_help,
108
+ help=f"""\
109
+ Manager for {tinv.long_name}s.
110
+
111
+ \b
112
+ Use '… {tname} -' to list all entries.
113
+ Use '… {tname} NAME' to show details of a single entry.
114
+ """,
115
+ )
116
+ @click.argument("name", type=str, nargs=1)
117
+ @click.pass_context
118
+ async def typ(ctx, name):
119
+ obj = ctx.obj
120
+ if tinv.prepare is not None:
121
+ await tinv.prepare(obj)
122
+
123
+ if name == "-":
124
+ if ctx.invoked_subcommand is not None:
125
+ raise click.BadParameter("The name '-' triggers a list and precludes subcommands.")
126
+ cnt = 0
127
+ for n in this(obj).all_children if tinv.list_recursive else this(obj):
128
+ cnt += 1
129
+ print(n, file=obj.stdout)
130
+ if not cnt and ctx.obj.debug:
131
+ print("no entries", file=sys.stderr)
132
+ elif ctx.invoked_subcommand is None:
133
+ # Show data from a single entry
134
+ n = this(obj).by_name(name)
135
+ if n is None:
136
+ raise KeyError(name)
137
+ cnt = 0
138
+ for k in n.ATTRS + getattr(n, "AUX_ATTRS", ()):
139
+ v = getattr(n, k, None)
140
+ if v is not None:
141
+ cnt += 1
142
+ if isinstance(v, dict):
143
+ v = v.items()
144
+ if isinstance(v, type({}.items())): # pylint: disable=W1116
145
+ for kk, vv in sorted(v):
146
+ if isinstance(vv, (tuple, list)):
147
+ if vv:
148
+ vv = " ".join(str(x) for x in vv)
149
+ else:
150
+ vv = "-"
151
+ elif isinstance(vv, dict):
152
+ vv = " ".join("%s=%s" % (x, y) for x, y in sorted(vv.items()))
153
+ print("%s %s %s" % (k, kk, vv), file=obj.stdout)
154
+ else:
155
+ print("%s %s" % (k, v), file=obj.stdout)
156
+ if not cnt and ctx.obj.debug:
157
+ print("exists, no data", file=sys.stderr)
158
+ else:
159
+ obj[tnname] = name
160
+ try:
161
+ obj[tname] = this(obj).by_name(name)
162
+ except KeyError:
163
+ obj[tname] = None
164
+
165
+ def alloc(obj, name):
166
+ # Allocate a new thing
167
+ if isinstance(name, (tuple, list)):
168
+ n = this(obj).follow(name, create=True)
169
+ else:
170
+ n = this(obj).allocate(name)
171
+ return n
172
+
173
+ # This is a hack for groups that take arguments. Doesn't work for
174
+ # multiple arguments, but you shouldn't do that anyway.
175
+ @typ.command("--help", hidden=True)
176
+ @click.pass_context
177
+ def help_(ctx): # pylint:disable=unused-variable # oh boy
178
+ print(typ.get_help(ctx))
179
+
180
+ @typ.command(short_help="Add a " + tinv.long_name)
181
+ @tinv.id_arg
182
+ @tinv.apply_aux
183
+ @click.pass_obj
184
+ async def add(obj, **kw):
185
+ name = obj[tnname]
186
+ if obj[tname] is not None:
187
+ raise RuntimeError(f"{name} already exists")
188
+ if tinv.id_name:
189
+ kw["name"] = name
190
+ n = alloc(obj, kw.pop(tinv.id_name))
191
+ else:
192
+ n = alloc(obj, name)
193
+
194
+ await _v_mod(obj, n, **kw)
195
+
196
+ add.__doc__ = f"""
197
+ Add a {tinv.long_name}
198
+ """
199
+
200
+ @typ.command("set", short_help="Modify a " + tinv.long_name)
201
+ @tinv.apply_aux
202
+ @click.pass_obj
203
+ async def set_(obj, **kw):
204
+ n = obj[tname]
205
+ if n is None:
206
+ raise KeyError(tname)
207
+
208
+ await _v_mod(obj, n, **kw)
209
+
210
+ set_.__doc__ = f"""
211
+ Modify a {tinv.long_name}
212
+ """
213
+
214
+ @typ.command(short_help="Delete a " + tinv.long_name)
215
+ @click.pass_obj
216
+ async def delete(obj, **kw): # pylint: disable=unused-argument,unused-variable
217
+ name = obj[tnname]
218
+ n = this(obj).by_name(name)
219
+ if n is not None:
220
+ await n.delete()
221
+
222
+ delete.__doc__ = """
223
+ Delete a {tinv.long_name}
224
+ """
225
+
226
+ async def _v_mod(obj, thing, **kw):
227
+ tinv.apply(obj, thing, kw)
228
+ for k, v in kw.items():
229
+ if v:
230
+ if v == "-":
231
+ v = None
232
+ try:
233
+ setattr(thing, k, v)
234
+ except AttributeError:
235
+ if k != "name":
236
+ raise AttributeError(k, v) from None
237
+ tinv.postproc(obj, thing, kw)
238
+ await thing.save()
239
+
240
+ # Finally, return the CLI so the user can attach more stuff
241
+ return typ