backend.ai-cli 24.12.0__py3-none-any.whl → 25.1.1__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.
Potentially problematic release.
This version of backend.ai-cli might be problematic. Click here for more details.
- ai/backend/cli/VERSION +1 -1
- ai/backend/cli/interaction.py +3 -3
- ai/backend/cli/params.py +73 -19
- {backend.ai_cli-24.12.0.dist-info → backend.ai_cli-25.1.1.dist-info}/METADATA +2 -2
- backend.ai_cli-25.1.1.dist-info/RECORD +16 -0
- backend.ai_cli-24.12.0.dist-info/RECORD +0 -16
- {backend.ai_cli-24.12.0.dist-info → backend.ai_cli-25.1.1.dist-info}/WHEEL +0 -0
- {backend.ai_cli-24.12.0.dist-info → backend.ai_cli-25.1.1.dist-info}/entry_points.txt +0 -0
- {backend.ai_cli-24.12.0.dist-info → backend.ai_cli-25.1.1.dist-info}/namespace_packages.txt +0 -0
- {backend.ai_cli-24.12.0.dist-info → backend.ai_cli-25.1.1.dist-info}/top_level.txt +0 -0
ai/backend/cli/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
25.1.1
|
ai/backend/cli/interaction.py
CHANGED
|
@@ -73,12 +73,12 @@ def ask_string_in_array(prompt: str, choices: list, default: str) -> Optional[st
|
|
|
73
73
|
|
|
74
74
|
if default:
|
|
75
75
|
question = (
|
|
76
|
-
f"{prompt} (choices: {
|
|
76
|
+
f"{prompt} (choices: {'/'.join(choices)}, "
|
|
77
77
|
f"if left empty, this will use default value: {default}): "
|
|
78
78
|
)
|
|
79
79
|
else:
|
|
80
80
|
question = (
|
|
81
|
-
f"{prompt} (choices: {
|
|
81
|
+
f"{prompt} (choices: {'/'.join(choices)}, if left empty, this will remove this key): "
|
|
82
82
|
)
|
|
83
83
|
|
|
84
84
|
while True:
|
|
@@ -92,7 +92,7 @@ def ask_string_in_array(prompt: str, choices: list, default: str) -> Optional[st
|
|
|
92
92
|
elif user_reply.lower() in choices:
|
|
93
93
|
break
|
|
94
94
|
else:
|
|
95
|
-
print(f"Please answer in {
|
|
95
|
+
print(f"Please answer in {'/'.join(choices)}.")
|
|
96
96
|
return user_reply
|
|
97
97
|
|
|
98
98
|
|
ai/backend/cli/params.py
CHANGED
|
@@ -1,7 +1,15 @@
|
|
|
1
1
|
import json
|
|
2
2
|
import re
|
|
3
|
+
from collections.abc import Mapping, Sequence
|
|
3
4
|
from decimal import Decimal
|
|
4
|
-
from typing import
|
|
5
|
+
from typing import (
|
|
6
|
+
Any,
|
|
7
|
+
Generic,
|
|
8
|
+
Optional,
|
|
9
|
+
Protocol,
|
|
10
|
+
TypeVar,
|
|
11
|
+
override,
|
|
12
|
+
)
|
|
5
13
|
|
|
6
14
|
import click
|
|
7
15
|
import trafaret
|
|
@@ -12,7 +20,13 @@ from .types import Undefined, undefined
|
|
|
12
20
|
class BoolExprType(click.ParamType):
|
|
13
21
|
name = "boolean"
|
|
14
22
|
|
|
15
|
-
|
|
23
|
+
@override
|
|
24
|
+
def convert(
|
|
25
|
+
self,
|
|
26
|
+
value: str,
|
|
27
|
+
param: Optional[click.Parameter],
|
|
28
|
+
ctx: Optional[click.Context],
|
|
29
|
+
) -> bool:
|
|
16
30
|
if isinstance(value, bool):
|
|
17
31
|
return value
|
|
18
32
|
try:
|
|
@@ -34,7 +48,13 @@ class ByteSizeParamType(click.ParamType):
|
|
|
34
48
|
"e": 2**60,
|
|
35
49
|
}
|
|
36
50
|
|
|
37
|
-
|
|
51
|
+
@override
|
|
52
|
+
def convert(
|
|
53
|
+
self,
|
|
54
|
+
value: str,
|
|
55
|
+
param: Optional[click.Parameter],
|
|
56
|
+
ctx: Optional[click.Context],
|
|
57
|
+
) -> Any:
|
|
38
58
|
if isinstance(value, int):
|
|
39
59
|
return value
|
|
40
60
|
if not isinstance(value, str):
|
|
@@ -54,7 +74,13 @@ class ByteSizeParamType(click.ParamType):
|
|
|
54
74
|
class ByteSizeParamCheckType(ByteSizeParamType):
|
|
55
75
|
name = "byte-check"
|
|
56
76
|
|
|
57
|
-
|
|
77
|
+
@override
|
|
78
|
+
def convert(
|
|
79
|
+
self,
|
|
80
|
+
value: str,
|
|
81
|
+
param: Optional[click.Parameter],
|
|
82
|
+
ctx: Optional[click.Context],
|
|
83
|
+
) -> str:
|
|
58
84
|
if isinstance(value, int):
|
|
59
85
|
return value
|
|
60
86
|
if not isinstance(value, str):
|
|
@@ -72,7 +98,13 @@ class ByteSizeParamCheckType(ByteSizeParamType):
|
|
|
72
98
|
class CommaSeparatedKVListParamType(click.ParamType):
|
|
73
99
|
name = "comma-seperated-KVList-check"
|
|
74
100
|
|
|
75
|
-
|
|
101
|
+
@override
|
|
102
|
+
def convert(
|
|
103
|
+
self,
|
|
104
|
+
value: str,
|
|
105
|
+
param: Optional[click.Parameter],
|
|
106
|
+
ctx: Optional[click.Context],
|
|
107
|
+
) -> Mapping[str, str]:
|
|
76
108
|
if isinstance(value, dict):
|
|
77
109
|
return value
|
|
78
110
|
if not isinstance(value, str):
|
|
@@ -111,9 +143,10 @@ class JSONParamType(click.ParamType):
|
|
|
111
143
|
super().__init__()
|
|
112
144
|
self._parsed = False
|
|
113
145
|
|
|
146
|
+
@override
|
|
114
147
|
def convert(
|
|
115
148
|
self,
|
|
116
|
-
value:
|
|
149
|
+
value: str,
|
|
117
150
|
param: Optional[click.Parameter],
|
|
118
151
|
ctx: Optional[click.Context],
|
|
119
152
|
) -> Any:
|
|
@@ -151,8 +184,14 @@ class RangeExprOptionType(click.ParamType):
|
|
|
151
184
|
_rx_range_key = re.compile(r"^[a-zA-Z_][a-zA-Z0-9_]*$")
|
|
152
185
|
name = "Range Expression"
|
|
153
186
|
|
|
154
|
-
|
|
155
|
-
|
|
187
|
+
@override
|
|
188
|
+
def convert(
|
|
189
|
+
self,
|
|
190
|
+
value: str,
|
|
191
|
+
param: Optional[click.Parameter],
|
|
192
|
+
ctx: Optional[click.Context],
|
|
193
|
+
) -> Any:
|
|
194
|
+
key, value = value.split("=", maxsplit=1)
|
|
156
195
|
assert self._rx_range_key.match(key), "The key must be a valid slug string."
|
|
157
196
|
try:
|
|
158
197
|
if value.startswith("case:"):
|
|
@@ -172,12 +211,18 @@ class RangeExprOptionType(click.ParamType):
|
|
|
172
211
|
class CommaSeparatedListType(click.ParamType):
|
|
173
212
|
name = "List Expression"
|
|
174
213
|
|
|
175
|
-
|
|
214
|
+
@override
|
|
215
|
+
def convert(
|
|
216
|
+
self,
|
|
217
|
+
value: str,
|
|
218
|
+
param: Optional[click.Parameter],
|
|
219
|
+
ctx: Optional[click.Context],
|
|
220
|
+
) -> Sequence[str]:
|
|
176
221
|
try:
|
|
177
|
-
if isinstance(
|
|
178
|
-
return
|
|
179
|
-
elif isinstance(
|
|
180
|
-
return
|
|
222
|
+
if isinstance(value, int):
|
|
223
|
+
return value
|
|
224
|
+
elif isinstance(value, str):
|
|
225
|
+
return value.split(",")
|
|
181
226
|
except ValueError as e:
|
|
182
227
|
self.fail(repr(e), param, ctx)
|
|
183
228
|
|
|
@@ -189,22 +234,31 @@ class SingleValueConstructorType(Protocol):
|
|
|
189
234
|
def __init__(self, value: Any) -> None: ...
|
|
190
235
|
|
|
191
236
|
|
|
192
|
-
TScalar = TypeVar("TScalar", bound=SingleValueConstructorType)
|
|
237
|
+
TScalar = TypeVar("TScalar", bound=SingleValueConstructorType | click.ParamType)
|
|
193
238
|
|
|
194
239
|
|
|
195
240
|
class OptionalType(click.ParamType, Generic[TScalar]):
|
|
196
241
|
name = "Optional Type Wrapper"
|
|
197
242
|
|
|
198
|
-
def __init__(self, type_: type[TScalar] |
|
|
243
|
+
def __init__(self, type_: type[TScalar] | click.ParamType) -> None:
|
|
199
244
|
super().__init__()
|
|
200
245
|
self.type_ = type_
|
|
201
246
|
|
|
202
|
-
def convert(
|
|
247
|
+
def convert(
|
|
248
|
+
self,
|
|
249
|
+
value: str,
|
|
250
|
+
param: Optional[click.Parameter],
|
|
251
|
+
ctx: Optional[click.Context],
|
|
252
|
+
) -> TScalar | Undefined:
|
|
203
253
|
try:
|
|
204
254
|
if value is undefined:
|
|
205
255
|
return undefined
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
256
|
+
match self.type_:
|
|
257
|
+
case click.ParamType():
|
|
258
|
+
return self.type_(value)
|
|
259
|
+
case type() if issubclass(self.type_, click.ParamType):
|
|
260
|
+
return self.type_()(value)
|
|
261
|
+
case _:
|
|
262
|
+
return self.type_(value)
|
|
209
263
|
except ValueError:
|
|
210
264
|
self.fail(f"{value!r} is not valid `{self.type_}` or `undefined`", param, ctx)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: backend.ai-cli
|
|
3
|
-
Version:
|
|
3
|
+
Version: 25.1.1
|
|
4
4
|
Summary: Backend.AI Command Line Interface Helper
|
|
5
5
|
Home-page: https://github.com/lablup/backend.ai
|
|
6
6
|
Author: Lablup Inc. and contributors
|
|
@@ -21,7 +21,7 @@ Classifier: License :: OSI Approved :: MIT License
|
|
|
21
21
|
Requires-Python: >=3.12,<3.13
|
|
22
22
|
Description-Content-Type: text/markdown
|
|
23
23
|
Requires-Dist: attrs>=24.2
|
|
24
|
-
Requires-Dist: backend.ai-plugin==
|
|
24
|
+
Requires-Dist: backend.ai-plugin==25.1.1
|
|
25
25
|
Requires-Dist: click~=8.1.7
|
|
26
26
|
Requires-Dist: trafaret~=2.1
|
|
27
27
|
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
ai/backend/cli/VERSION,sha256=MWTWBShfNdB-wZgctarAHHDrXGZkWatLBGloNv71PJg,6
|
|
2
|
+
ai/backend/cli/__init__.py,sha256=cID1jLnC_vj48GgMN6Yb1FA3JsQ95zNmCHmRYE8TFhY,22
|
|
3
|
+
ai/backend/cli/__main__.py,sha256=Rp61ckhVRXFk_0BywIRgbiOzkR_gLq2cyyiDyLsB8UI,291
|
|
4
|
+
ai/backend/cli/extensions.py,sha256=twjloigQl4VTBU8gP6YMZNGi3dUDW4V_i-yVX12HRH0,5125
|
|
5
|
+
ai/backend/cli/interaction.py,sha256=L-6kvJbxMw9YeO_NT78wortS_Db0Qx9W8XiY56JgorI,4982
|
|
6
|
+
ai/backend/cli/loader.py,sha256=yWyNyvFJORtFFQfcL-vqwD5NbRxAHxS_uH1878r9EIA,1140
|
|
7
|
+
ai/backend/cli/main.py,sha256=8HpGUH5k0uv6lKVqKoctW3vd9hm1xo_j06HSCvyRvgw,707
|
|
8
|
+
ai/backend/cli/params.py,sha256=DpgxQpRR2U1GC5mmod00neHne77VDunXIGo_hL4bUgU,7468
|
|
9
|
+
ai/backend/cli/py.typed,sha256=QJeIkjairybCkwM_65ZMTPEYwCJODQY_7AqJ6dBWnvI,11
|
|
10
|
+
ai/backend/cli/types.py,sha256=mThxfeGD6MsHt0OkMdw1LvjufENHYbYZXcgRVNpmD5o,734
|
|
11
|
+
backend.ai_cli-25.1.1.dist-info/METADATA,sha256=n7v0GsUU8Uht1mx-_rtVzB6Bkr6INW5WnoxBN6WM1CE,1730
|
|
12
|
+
backend.ai_cli-25.1.1.dist-info/WHEEL,sha256=GV9aMThwP_4oNCtvEC2ec3qUYutgWeAzklro_0m4WJQ,91
|
|
13
|
+
backend.ai_cli-25.1.1.dist-info/entry_points.txt,sha256=lOiEpT48ETF_ht5fFVQugAjZSuZr-wkGYZzfC5YTnuY,60
|
|
14
|
+
backend.ai_cli-25.1.1.dist-info/namespace_packages.txt,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
|
|
15
|
+
backend.ai_cli-25.1.1.dist-info/top_level.txt,sha256=TJAp5TUfTUztZSUatbygths7CWRrFfnOMCtZ-DIcw6c,3
|
|
16
|
+
backend.ai_cli-25.1.1.dist-info/RECORD,,
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
ai/backend/cli/VERSION,sha256=JfC4XOJ8U90ct3quVEPEw9O9UpWZKlgkf6FvYWG9D_0,7
|
|
2
|
-
ai/backend/cli/__init__.py,sha256=cID1jLnC_vj48GgMN6Yb1FA3JsQ95zNmCHmRYE8TFhY,22
|
|
3
|
-
ai/backend/cli/__main__.py,sha256=Rp61ckhVRXFk_0BywIRgbiOzkR_gLq2cyyiDyLsB8UI,291
|
|
4
|
-
ai/backend/cli/extensions.py,sha256=twjloigQl4VTBU8gP6YMZNGi3dUDW4V_i-yVX12HRH0,5125
|
|
5
|
-
ai/backend/cli/interaction.py,sha256=wdRa5aBWebW_bffGwRSBs3lVB4CJtc0gNAx1u6084Ss,4982
|
|
6
|
-
ai/backend/cli/loader.py,sha256=yWyNyvFJORtFFQfcL-vqwD5NbRxAHxS_uH1878r9EIA,1140
|
|
7
|
-
ai/backend/cli/main.py,sha256=8HpGUH5k0uv6lKVqKoctW3vd9hm1xo_j06HSCvyRvgw,707
|
|
8
|
-
ai/backend/cli/params.py,sha256=hnZNXGKTsNDOlPHXDB3Tnk1p8xtWIDFM649U8WPSv38,6436
|
|
9
|
-
ai/backend/cli/py.typed,sha256=QJeIkjairybCkwM_65ZMTPEYwCJODQY_7AqJ6dBWnvI,11
|
|
10
|
-
ai/backend/cli/types.py,sha256=mThxfeGD6MsHt0OkMdw1LvjufENHYbYZXcgRVNpmD5o,734
|
|
11
|
-
backend.ai_cli-24.12.0.dist-info/METADATA,sha256=cIenv01jbp2nyUyN35B72hCc175MCU1kwCRCne5zmB8,1732
|
|
12
|
-
backend.ai_cli-24.12.0.dist-info/WHEEL,sha256=GV9aMThwP_4oNCtvEC2ec3qUYutgWeAzklro_0m4WJQ,91
|
|
13
|
-
backend.ai_cli-24.12.0.dist-info/entry_points.txt,sha256=lOiEpT48ETF_ht5fFVQugAjZSuZr-wkGYZzfC5YTnuY,60
|
|
14
|
-
backend.ai_cli-24.12.0.dist-info/namespace_packages.txt,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
|
|
15
|
-
backend.ai_cli-24.12.0.dist-info/top_level.txt,sha256=TJAp5TUfTUztZSUatbygths7CWRrFfnOMCtZ-DIcw6c,3
|
|
16
|
-
backend.ai_cli-24.12.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|