ominfra 0.0.0.dev200__py3-none-any.whl → 0.0.0.dev202__py3-none-any.whl
Sign up to get free protection for your applications and to get access to all the features.
- ominfra/clouds/aws/models/gen/cli.py +10 -1
- ominfra/clouds/aws/models/gen/gen.py +73 -16
- 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 +527 -9
- ominfra/clouds/aws/models/services/services.toml +25 -0
- ominfra/commands/__init__.py +0 -0
- ominfra/{ssh.py → commands/ssh.py} +2 -2
- ominfra/scripts/manage.py +1 -2
- {ominfra-0.0.0.dev200.dist-info → ominfra-0.0.0.dev202.dist-info}/METADATA +4 -4
- {ominfra-0.0.0.dev200.dist-info → ominfra-0.0.0.dev202.dist-info}/RECORD +17 -14
- /ominfra/{cmds.py → commands/runners.py} +0 -0
- {ominfra-0.0.0.dev200.dist-info → ominfra-0.0.0.dev202.dist-info}/LICENSE +0 -0
- {ominfra-0.0.0.dev200.dist-info → ominfra-0.0.0.dev202.dist-info}/WHEEL +0 -0
- {ominfra-0.0.0.dev200.dist-info → ominfra-0.0.0.dev202.dist-info}/entry_points.txt +0 -0
- {ominfra-0.0.0.dev200.dist-info → ominfra-0.0.0.dev202.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
|
|
@@ -384,7 +441,7 @@ class ModelGen:
|
|
384
441
|
|
385
442
|
if operation.error_shapes:
|
386
443
|
fls.append('errors=[')
|
387
|
-
for osn in
|
444
|
+
for osn in sorted(es.name for es in operation.error_shapes):
|
388
445
|
fls.append(f' {osn},')
|
389
446
|
fls.append('],')
|
390
447
|
|
@@ -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
|
|