ominfra 0.0.0.dev200__py3-none-any.whl → 0.0.0.dev201__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.
- ominfra/clouds/aws/models/gen/cli.py +10 -1
- ominfra/clouds/aws/models/gen/gen.py +72 -15
- ominfra/clouds/aws/models/services/ec2.py +1998 -127
- ominfra/clouds/aws/models/services/lambda_.py +864 -0
- ominfra/clouds/aws/models/services/rds.py +1898 -0
- ominfra/clouds/aws/models/services/s3.py +525 -7
- ominfra/clouds/aws/models/services/services.toml +25 -0
- ominfra/commands/__init__.py +0 -0
- ominfra/{ssh.py → commands/ssh.py} +2 -2
- {ominfra-0.0.0.dev200.dist-info → ominfra-0.0.0.dev201.dist-info}/METADATA +4 -4
- {ominfra-0.0.0.dev200.dist-info → ominfra-0.0.0.dev201.dist-info}/RECORD +16 -13
- /ominfra/{cmds.py → commands/runners.py} +0 -0
- {ominfra-0.0.0.dev200.dist-info → ominfra-0.0.0.dev201.dist-info}/LICENSE +0 -0
- {ominfra-0.0.0.dev200.dist-info → ominfra-0.0.0.dev201.dist-info}/WHEEL +0 -0
- {ominfra-0.0.0.dev200.dist-info → ominfra-0.0.0.dev201.dist-info}/entry_points.txt +0 -0
- {ominfra-0.0.0.dev200.dist-info → ominfra-0.0.0.dev201.dist-info}/top_level.txt +0 -0
@@ -1,4 +1,5 @@
|
|
1
1
|
import dataclasses as dc
|
2
|
+
import keyword
|
2
3
|
import os.path
|
3
4
|
import sys
|
4
5
|
import typing as ta
|
@@ -78,7 +79,10 @@ class Cli(ap.Cli):
|
|
78
79
|
operation_names=svc.operations,
|
79
80
|
)
|
80
81
|
|
81
|
-
|
82
|
+
fn = svc.name
|
83
|
+
if fn in keyword.kwlist:
|
84
|
+
fn += '_'
|
85
|
+
output_file = os.path.join(output_dir, f'{fn}.py')
|
82
86
|
with open(output_file, 'w') as f:
|
83
87
|
f.write(mod)
|
84
88
|
|
@@ -105,6 +109,11 @@ class Cli(ap.Cli):
|
|
105
109
|
|
106
110
|
#
|
107
111
|
|
112
|
+
@ap.cmd()
|
113
|
+
def list_services(self) -> None:
|
114
|
+
for name in sorted(ModelGen.list_available_services()):
|
115
|
+
print(name)
|
116
|
+
|
108
117
|
@ap.cmd(
|
109
118
|
ap.arg('service'),
|
110
119
|
)
|
@@ -3,6 +3,7 @@ TODO:
|
|
3
3
|
- default values? nullability? maybe a new_default helper?
|
4
4
|
- relative import base
|
5
5
|
"""
|
6
|
+
import builtins
|
6
7
|
import dataclasses as dc
|
7
8
|
import io
|
8
9
|
import typing as ta
|
@@ -13,10 +14,12 @@ from omlish import lang
|
|
13
14
|
|
14
15
|
|
15
16
|
if ta.TYPE_CHECKING:
|
17
|
+
import botocore.loaders
|
16
18
|
import botocore.model
|
17
19
|
import botocore.session
|
18
20
|
else:
|
19
21
|
botocore = lang.proxy_import('botocore', extras=[
|
22
|
+
'loaders',
|
20
23
|
'model',
|
21
24
|
'session',
|
22
25
|
])
|
@@ -25,6 +28,13 @@ else:
|
|
25
28
|
##
|
26
29
|
|
27
30
|
|
31
|
+
ServiceTypeName: ta.TypeAlias = ta.Literal[
|
32
|
+
'service-2',
|
33
|
+
'paginators-1',
|
34
|
+
'waiters-2',
|
35
|
+
]
|
36
|
+
|
37
|
+
|
28
38
|
class ModelGen:
|
29
39
|
def __init__(
|
30
40
|
self,
|
@@ -53,16 +63,29 @@ class ModelGen:
|
|
53
63
|
|
54
64
|
#
|
55
65
|
|
66
|
+
@classmethod
|
67
|
+
def create_data_loader(cls) -> 'botocore.loaders.Loader':
|
68
|
+
session = botocore.session.get_session()
|
69
|
+
return session.get_component('data_loader')
|
70
|
+
|
71
|
+
@classmethod
|
72
|
+
def list_available_services(
|
73
|
+
cls,
|
74
|
+
*,
|
75
|
+
type_name: ServiceTypeName = 'service-2',
|
76
|
+
) -> list[str]:
|
77
|
+
loader = cls.create_data_loader()
|
78
|
+
return list(loader.list_available_services(type_name))
|
79
|
+
|
56
80
|
@classmethod
|
57
81
|
def load_service_model(
|
58
82
|
cls,
|
59
83
|
service_name: str,
|
60
84
|
*,
|
61
|
-
type_name:
|
85
|
+
type_name: ServiceTypeName = 'service-2',
|
62
86
|
api_version: str | None = None,
|
63
87
|
) -> 'botocore.model.ServiceModel':
|
64
|
-
|
65
|
-
loader = session.get_component('data_loader')
|
88
|
+
loader = cls.create_data_loader()
|
66
89
|
json_model = loader.load_service_model(service_name, type_name, api_version=api_version)
|
67
90
|
return botocore.model.ServiceModel(json_model, service_name=service_name)
|
68
91
|
|
@@ -137,6 +160,7 @@ class ModelGen:
|
|
137
160
|
pass
|
138
161
|
|
139
162
|
if name in self._shape_names:
|
163
|
+
name = self.sanitize_class_name(name)
|
140
164
|
if not unquoted_names:
|
141
165
|
return f"'{name}'"
|
142
166
|
else:
|
@@ -150,44 +174,69 @@ class ModelGen:
|
|
150
174
|
'AAAA',
|
151
175
|
'ACL',
|
152
176
|
'ACP',
|
177
|
+
'AES',
|
178
|
+
'AES256',
|
179
|
+
'AZ',
|
180
|
+
'CA',
|
153
181
|
'CRC32',
|
154
182
|
'CRC32C',
|
183
|
+
'DB',
|
184
|
+
'EFS',
|
155
185
|
'ETag',
|
186
|
+
'IAM',
|
187
|
+
'IO',
|
188
|
+
'IP',
|
189
|
+
'JSON',
|
156
190
|
'KMS',
|
157
191
|
'MD5',
|
158
192
|
'MFA',
|
159
193
|
'SHA1',
|
160
194
|
'SHA256',
|
161
195
|
'SSE',
|
196
|
+
'TTL',
|
162
197
|
]
|
163
198
|
|
164
199
|
def demangle_name(self, n: str) -> str:
|
165
200
|
ps: list[str] = []
|
166
201
|
while n:
|
167
202
|
ms: list[tuple[str, int]] = []
|
203
|
+
|
168
204
|
for pfx in self.DEMANGLE_PREFIXES:
|
169
205
|
if (i := n.find(pfx)) >= 0:
|
170
206
|
ms.append((pfx, i))
|
207
|
+
|
171
208
|
if not ms:
|
172
209
|
ps.append(n)
|
173
210
|
break
|
211
|
+
|
174
212
|
if len(ms) > 1:
|
175
213
|
m = sorted(ms, key=lambda t: (t[1], -len(t[0])))[0]
|
176
214
|
else:
|
177
215
|
m = ms[0]
|
216
|
+
|
178
217
|
pfx, i = m
|
179
218
|
l, r = n[:i], n[i + len(pfx):]
|
219
|
+
|
180
220
|
if l:
|
181
221
|
ps.append(l)
|
182
222
|
ps.append(pfx.lower())
|
223
|
+
|
183
224
|
n = r
|
225
|
+
|
184
226
|
return '_'.join(lang.snake_case(p) for p in ps)
|
185
227
|
|
186
228
|
#
|
187
229
|
|
230
|
+
def sanitize_class_name(self, n: str) -> str:
|
231
|
+
if hasattr(builtins, n):
|
232
|
+
n += '_'
|
233
|
+
return n
|
234
|
+
|
235
|
+
#
|
236
|
+
|
188
237
|
PREAMBLE_LINES: ta.Sequence[str] = [
|
189
238
|
'# flake8: noqa: E501',
|
190
|
-
'# ruff: noqa: S105',
|
239
|
+
'# ruff: noqa: N801 S105',
|
191
240
|
'# fmt: off',
|
192
241
|
'import dataclasses as _dc # noqa',
|
193
242
|
'import enum as _enum # noqa',
|
@@ -229,6 +278,8 @@ class ModelGen:
|
|
229
278
|
) -> ShapeSrc:
|
230
279
|
shape: botocore.model.Shape = self._service_model.shape_for(name)
|
231
280
|
|
281
|
+
san_name = self.sanitize_class_name(shape.name)
|
282
|
+
|
232
283
|
if isinstance(shape, botocore.model.StructureShape):
|
233
284
|
lines: list[str] = []
|
234
285
|
|
@@ -238,7 +289,7 @@ class ModelGen:
|
|
238
289
|
|
239
290
|
lines.extend([
|
240
291
|
'@_dc.dataclass(frozen=True)',
|
241
|
-
f'class {
|
292
|
+
f'class {san_name}(',
|
242
293
|
' _base.Shape,',
|
243
294
|
*[f' {dl},' for dl in mds],
|
244
295
|
'):',
|
@@ -247,7 +298,9 @@ class ModelGen:
|
|
247
298
|
if not shape.members:
|
248
299
|
lines.append(' pass')
|
249
300
|
|
250
|
-
for mn, ms in shape.members.items():
|
301
|
+
for i, (mn, ms) in enumerate(shape.members.items()):
|
302
|
+
if i:
|
303
|
+
lines.append('')
|
251
304
|
fn = self.demangle_name(mn)
|
252
305
|
mds = [
|
253
306
|
f'member_name={mn!r}',
|
@@ -268,7 +321,7 @@ class ModelGen:
|
|
268
321
|
|
269
322
|
return self.ShapeSrc(
|
270
323
|
'\n'.join(lines),
|
271
|
-
class_name=
|
324
|
+
class_name=san_name,
|
272
325
|
double_space=True,
|
273
326
|
)
|
274
327
|
|
@@ -278,7 +331,7 @@ class ModelGen:
|
|
278
331
|
mn,
|
279
332
|
unquoted_names=unquoted_names,
|
280
333
|
)
|
281
|
-
l = f'{
|
334
|
+
l = f'{san_name}: _ta.TypeAlias = _ta.Sequence[{ma or mn}]'
|
282
335
|
if ma is None:
|
283
336
|
l = '# ' + l
|
284
337
|
return self.ShapeSrc(l)
|
@@ -295,7 +348,7 @@ class ModelGen:
|
|
295
348
|
vn,
|
296
349
|
unquoted_names=unquoted_names,
|
297
350
|
)
|
298
|
-
l = f'{
|
351
|
+
l = f'{san_name}: _ta.TypeAlias = _ta.Mapping[{ka or kn}, {va or vn}]'
|
299
352
|
if ka is None or va is None:
|
300
353
|
l = '# ' + l
|
301
354
|
return self.ShapeSrc(l)
|
@@ -303,10 +356,14 @@ class ModelGen:
|
|
303
356
|
elif isinstance(shape, botocore.model.StringShape):
|
304
357
|
if shape.enum:
|
305
358
|
ls = [
|
306
|
-
f'class {
|
359
|
+
f'class {san_name}(_enum.Enum):',
|
307
360
|
]
|
361
|
+
all_caps = all(v == v.upper() for v in shape.enum)
|
308
362
|
for v in shape.enum:
|
309
|
-
n = v
|
363
|
+
n = v
|
364
|
+
if not all_caps:
|
365
|
+
n = self.demangle_name(n)
|
366
|
+
n = n.upper()
|
310
367
|
for c in '.-:':
|
311
368
|
n = n.replace(c, '_')
|
312
369
|
ls.append(f' {n} = {v!r}')
|
@@ -316,10 +373,10 @@ class ModelGen:
|
|
316
373
|
)
|
317
374
|
|
318
375
|
else:
|
319
|
-
return self.ShapeSrc(f"{
|
376
|
+
return self.ShapeSrc(f"{san_name} = _ta.NewType('{san_name}', str)")
|
320
377
|
|
321
378
|
elif (pt := self.PRIMITIVE_SHAPE_TYPES.get(shape.type_name)) is not None:
|
322
|
-
return self.ShapeSrc(f
|
379
|
+
return self.ShapeSrc(f'{san_name} = _ta.NewType({san_name!r}, {pt})')
|
323
380
|
|
324
381
|
else:
|
325
382
|
raise TypeError(shape.type_name)
|
@@ -354,7 +411,7 @@ class ModelGen:
|
|
354
411
|
|
355
412
|
out.write('\n\n')
|
356
413
|
out.write('ALL_SHAPES: frozenset[type[_base.Shape]] = frozenset([\n')
|
357
|
-
for n in all_shapes:
|
414
|
+
for n in sorted(all_shapes):
|
358
415
|
out.write(f' {n},\n')
|
359
416
|
out.write('])\n')
|
360
417
|
|
@@ -415,7 +472,7 @@ class ModelGen:
|
|
415
472
|
|
416
473
|
out.write('\n')
|
417
474
|
out.write('ALL_OPERATIONS: frozenset[_base.Operation] = frozenset([\n')
|
418
|
-
for n in all_operations:
|
475
|
+
for n in sorted(all_operations):
|
419
476
|
out.write(f' {n},\n')
|
420
477
|
out.write('])\n')
|
421
478
|
|