backend.ai-cli 24.3.0.dev1__tar.gz → 24.3.0rc1__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.

Potentially problematic release.


This version of backend.ai-cli might be problematic. Click here for more details.

Files changed (25) hide show
  1. {backend.ai-cli-24.3.0.dev1 → backend.ai-cli-24.3.0rc1}/PKG-INFO +2 -2
  2. backend.ai-cli-24.3.0rc1/ai/backend/cli/VERSION +1 -0
  3. backend.ai-cli-24.3.0rc1/ai/backend/cli/params.py +210 -0
  4. {backend.ai-cli-24.3.0.dev1 → backend.ai-cli-24.3.0rc1}/ai/backend/cli/types.py +22 -0
  5. {backend.ai-cli-24.3.0.dev1 → backend.ai-cli-24.3.0rc1}/backend.ai_cli.egg-info/PKG-INFO +2 -2
  6. {backend.ai-cli-24.3.0.dev1 → backend.ai-cli-24.3.0rc1}/backend.ai_cli.egg-info/SOURCES.txt +1 -0
  7. backend.ai-cli-24.3.0rc1/backend.ai_cli.egg-info/requires.txt +4 -0
  8. {backend.ai-cli-24.3.0.dev1 → backend.ai-cli-24.3.0rc1}/setup.py +6 -3
  9. backend.ai-cli-24.3.0.dev1/ai/backend/cli/VERSION +0 -1
  10. backend.ai-cli-24.3.0.dev1/backend.ai_cli.egg-info/requires.txt +0 -3
  11. {backend.ai-cli-24.3.0.dev1 → backend.ai-cli-24.3.0rc1}/MANIFEST.in +0 -0
  12. {backend.ai-cli-24.3.0.dev1 → backend.ai-cli-24.3.0rc1}/ai/backend/cli/__init__.py +0 -0
  13. {backend.ai-cli-24.3.0.dev1 → backend.ai-cli-24.3.0rc1}/ai/backend/cli/__main__.py +0 -0
  14. {backend.ai-cli-24.3.0.dev1 → backend.ai-cli-24.3.0rc1}/ai/backend/cli/extensions.py +0 -0
  15. {backend.ai-cli-24.3.0.dev1 → backend.ai-cli-24.3.0rc1}/ai/backend/cli/interaction.py +0 -0
  16. {backend.ai-cli-24.3.0.dev1 → backend.ai-cli-24.3.0rc1}/ai/backend/cli/loader.py +0 -0
  17. {backend.ai-cli-24.3.0.dev1 → backend.ai-cli-24.3.0rc1}/ai/backend/cli/main.py +0 -0
  18. {backend.ai-cli-24.3.0.dev1 → backend.ai-cli-24.3.0rc1}/ai/backend/cli/py.typed +0 -0
  19. {backend.ai-cli-24.3.0.dev1 → backend.ai-cli-24.3.0rc1}/backend.ai_cli.egg-info/dependency_links.txt +0 -0
  20. {backend.ai-cli-24.3.0.dev1 → backend.ai-cli-24.3.0rc1}/backend.ai_cli.egg-info/entry_points.txt +0 -0
  21. {backend.ai-cli-24.3.0.dev1 → backend.ai-cli-24.3.0rc1}/backend.ai_cli.egg-info/namespace_packages.txt +0 -0
  22. {backend.ai-cli-24.3.0.dev1 → backend.ai-cli-24.3.0rc1}/backend.ai_cli.egg-info/not-zip-safe +0 -0
  23. {backend.ai-cli-24.3.0.dev1 → backend.ai-cli-24.3.0rc1}/backend.ai_cli.egg-info/top_level.txt +0 -0
  24. {backend.ai-cli-24.3.0.dev1 → backend.ai-cli-24.3.0rc1}/backend_shim.py +0 -0
  25. {backend.ai-cli-24.3.0.dev1 → backend.ai-cli-24.3.0rc1}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: backend.ai-cli
3
- Version: 24.3.0.dev1
3
+ Version: 24.3.0rc1
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
@@ -15,7 +15,7 @@ Classifier: Programming Language :: Python :: 3
15
15
  Classifier: Environment :: No Input/Output (Daemon)
16
16
  Classifier: Topic :: Scientific/Engineering
17
17
  Classifier: Topic :: Software Development
18
- Classifier: Development Status :: 2 - Pre-Alpha
18
+ Classifier: Development Status :: 4 - Beta
19
19
  Classifier: Programming Language :: Python :: 3.11
20
20
  Classifier: License :: OSI Approved :: MIT License
21
21
  Requires-Python: >=3.11,<3.12
@@ -0,0 +1 @@
1
+ 24.03.0rc1
@@ -0,0 +1,210 @@
1
+ import json
2
+ import re
3
+ from decimal import Decimal
4
+ from typing import Any, Generic, Mapping, Optional, Protocol, TypeVar, Union
5
+
6
+ import click
7
+ import trafaret
8
+
9
+ from .types import Undefined, undefined
10
+
11
+
12
+ class BoolExprType(click.ParamType):
13
+ name = "boolean"
14
+
15
+ def convert(self, value, param, ctx):
16
+ if isinstance(value, bool):
17
+ return value
18
+ try:
19
+ return trafaret.ToBool().check(value)
20
+ except trafaret.DataError:
21
+ self.fail(f"Cannot parser/convert {value!r} as a boolean.", param, ctx)
22
+
23
+
24
+ class ByteSizeParamType(click.ParamType):
25
+ name = "byte"
26
+
27
+ _rx_digits = re.compile(r"^(\d+(?:\.\d*)?)([kmgtpe]?)$", re.I)
28
+ _scales = {
29
+ "k": 2**10,
30
+ "m": 2**20,
31
+ "g": 2**30,
32
+ "t": 2**40,
33
+ "p": 2**50,
34
+ "e": 2**60,
35
+ }
36
+
37
+ def convert(self, value, param, ctx):
38
+ if isinstance(value, int):
39
+ return value
40
+ if not isinstance(value, str):
41
+ self.fail(
42
+ f"expected string, got {value!r} of type {type(value).__name__}",
43
+ param,
44
+ ctx,
45
+ )
46
+ m = self._rx_digits.search(value)
47
+ if m is None:
48
+ self.fail(f"{value!r} is not a valid byte-size expression", param, ctx)
49
+ size = float(m.group(1))
50
+ unit = m.group(2).lower()
51
+ return int(size * self._scales.get(unit, 1))
52
+
53
+
54
+ class ByteSizeParamCheckType(ByteSizeParamType):
55
+ name = "byte-check"
56
+
57
+ def convert(self, value, param, ctx):
58
+ if isinstance(value, int):
59
+ return value
60
+ if not isinstance(value, str):
61
+ self.fail(
62
+ f"expected string, got {value!r} of type {type(value).__name__}",
63
+ param,
64
+ ctx,
65
+ )
66
+ m = self._rx_digits.search(value)
67
+ if m is None:
68
+ self.fail(f"{value!r} is not a valid byte-size expression", param, ctx)
69
+ return value
70
+
71
+
72
+ class CommaSeparatedKVListParamType(click.ParamType):
73
+ name = "comma-seperated-KVList-check"
74
+
75
+ def convert(self, value: Union[str, Mapping[str, str]], param, ctx) -> Mapping[str, str]:
76
+ if isinstance(value, dict):
77
+ return value
78
+ if not isinstance(value, str):
79
+ self.fail(
80
+ f"expected string, got {value!r} of type {type(value).__name__}",
81
+ param,
82
+ ctx,
83
+ )
84
+ override_map = {}
85
+ for assignment in value.split(","):
86
+ try:
87
+ k, _, v = assignment.partition("=")
88
+ if k == "" or v == "":
89
+ raise ValueError(f"key or value is empty. key = {k}, value = {v}")
90
+ except ValueError:
91
+ self.fail(
92
+ f"{value!r} is not a valid mapping expression",
93
+ param,
94
+ ctx,
95
+ )
96
+ else:
97
+ override_map[k] = v
98
+ return override_map
99
+
100
+
101
+ class JSONParamType(click.ParamType):
102
+ """
103
+ A JSON string parameter type.
104
+ The default value must be given as a valid JSON-parsable string,
105
+ not the Python objects.
106
+ """
107
+
108
+ name = "json-string"
109
+
110
+ def __init__(self) -> None:
111
+ super().__init__()
112
+ self._parsed = False
113
+
114
+ def convert(
115
+ self,
116
+ value: Optional[str],
117
+ param: Optional[click.Parameter],
118
+ ctx: Optional[click.Context],
119
+ ) -> Any:
120
+ if self._parsed:
121
+ # Click invokes this method TWICE
122
+ # for a default value given as string.
123
+ return value
124
+ self._parsed = True
125
+ if value is None:
126
+ return None
127
+ try:
128
+ return json.loads(value)
129
+ except json.JSONDecodeError:
130
+ self.fail(f"cannot parse {value!r} as JSON", param, ctx)
131
+
132
+
133
+ def drange(start: Decimal, stop: Decimal, num: int):
134
+ """
135
+ A simplified version of numpy.linspace with default options
136
+ """
137
+ delta = stop - start
138
+ step = delta / (num - 1)
139
+ yield from (start + step * Decimal(tick) for tick in range(0, num))
140
+
141
+
142
+ class RangeExprOptionType(click.ParamType):
143
+ """
144
+ Accepts a range expression which generates a range of values for a variable.
145
+
146
+ Linear space range: "linspace:1,2,10" (start, stop, num) as in numpy.linspace
147
+ Pythonic range: "range:1,10,2" (start, stop[, step]) as in Python's range
148
+ Case range: "case:a,b,c" (comma-separated strings)
149
+ """
150
+
151
+ _rx_range_key = re.compile(r"^[a-zA-Z_][a-zA-Z0-9_]*$")
152
+ name = "Range Expression"
153
+
154
+ def convert(self, arg, param, ctx):
155
+ key, value = arg.split("=", maxsplit=1)
156
+ assert self._rx_range_key.match(key), "The key must be a valid slug string."
157
+ try:
158
+ if value.startswith("case:"):
159
+ return key, value[5:].split(",")
160
+ elif value.startswith("linspace:"):
161
+ start, stop, num = value[9:].split(",")
162
+ return key, tuple(drange(Decimal(start), Decimal(stop), int(num)))
163
+ elif value.startswith("range:"):
164
+ range_args = map(int, value[6:].split(","))
165
+ return key, tuple(range(*range_args))
166
+ else:
167
+ self.fail("Unrecognized range expression type", param, ctx)
168
+ except ValueError as e:
169
+ self.fail(str(e), param, ctx)
170
+
171
+
172
+ class CommaSeparatedListType(click.ParamType):
173
+ name = "List Expression"
174
+
175
+ def convert(self, arg, param, ctx):
176
+ try:
177
+ if isinstance(arg, int):
178
+ return arg
179
+ elif isinstance(arg, str):
180
+ return arg.split(",")
181
+ except ValueError as e:
182
+ self.fail(repr(e), param, ctx)
183
+
184
+
185
+ T = TypeVar("T")
186
+
187
+
188
+ class SingleValueConstructorType(Protocol):
189
+ def __init__(self, value: Any) -> None: ...
190
+
191
+
192
+ TScalar = TypeVar("TScalar", bound=SingleValueConstructorType)
193
+
194
+
195
+ class OptionalType(click.ParamType, Generic[TScalar]):
196
+ name = "Optional Type Wrapper"
197
+
198
+ def __init__(self, type_: type[TScalar] | type[click.ParamType]) -> None:
199
+ super().__init__()
200
+ self.type_ = type_
201
+
202
+ def convert(self, value: Any, param, ctx) -> TScalar | Undefined:
203
+ try:
204
+ if value is undefined:
205
+ return undefined
206
+ if issubclass(self.type_, click.ParamType):
207
+ return self.type_()(value)
208
+ return self.type_(value)
209
+ except ValueError:
210
+ self.fail(f"{value!r} is not valid `{self.type_}` or `undefined`", param, ctx)
@@ -1,8 +1,15 @@
1
+ from __future__ import annotations
2
+
1
3
  import enum
2
4
  from typing import Dict
3
5
 
4
6
  import attr
5
7
 
8
+ __all__ = (
9
+ "Undefined",
10
+ "undefined",
11
+ )
12
+
6
13
 
7
14
  @attr.define(slots=True)
8
15
  class CliContextInfo:
@@ -15,3 +22,18 @@ class ExitCode(enum.IntEnum):
15
22
  INVALID_USAGE = 2 # wraps Click's UsageError
16
23
  OPERATION_TIMEOUT = 3 # timeout during operation
17
24
  INVALID_ARGUMENT = 4 # invalid argument while it's not UsageError
25
+
26
+
27
+ class Undefined(enum.Enum):
28
+ """
29
+ A special type to represent an undefined value.
30
+ """
31
+
32
+ TOKEN = 0
33
+
34
+ def __bool__(self) -> bool:
35
+ # It should be evaluated as False when used as a boolean expr.
36
+ return False
37
+
38
+
39
+ undefined = Undefined.TOKEN
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: backend.ai-cli
3
- Version: 24.3.0.dev1
3
+ Version: 24.3.0rc1
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
@@ -15,7 +15,7 @@ Classifier: Programming Language :: Python :: 3
15
15
  Classifier: Environment :: No Input/Output (Daemon)
16
16
  Classifier: Topic :: Scientific/Engineering
17
17
  Classifier: Topic :: Software Development
18
- Classifier: Development Status :: 2 - Pre-Alpha
18
+ Classifier: Development Status :: 4 - Beta
19
19
  Classifier: Programming Language :: Python :: 3.11
20
20
  Classifier: License :: OSI Approved :: MIT License
21
21
  Requires-Python: >=3.11,<3.12
@@ -8,6 +8,7 @@ ai/backend/cli/extensions.py
8
8
  ai/backend/cli/interaction.py
9
9
  ai/backend/cli/loader.py
10
10
  ai/backend/cli/main.py
11
+ ai/backend/cli/params.py
11
12
  ai/backend/cli/py.typed
12
13
  ai/backend/cli/types.py
13
14
  backend.ai_cli.egg-info/PKG-INFO
@@ -0,0 +1,4 @@
1
+ attrs>=20.3
2
+ backend.ai-plugin==24.03.0rc1
3
+ click~=8.1.7
4
+ trafaret~=2.1
@@ -15,7 +15,7 @@ setup(**{
15
15
  'Environment :: No Input/Output (Daemon)',
16
16
  'Topic :: Scientific/Engineering',
17
17
  'Topic :: Software Development',
18
- 'Development Status :: 2 - Pre-Alpha',
18
+ 'Development Status :: 4 - Beta',
19
19
  'Programming Language :: Python :: 3.11',
20
20
  'License :: OSI Approved :: MIT License',
21
21
  ],
@@ -27,8 +27,10 @@ setup(**{
27
27
  },
28
28
  'install_requires': (
29
29
  'attrs>=20.3',
30
- 'backend.ai-plugin==24.03.0dev1',
30
+ """backend.ai-plugin==24.03.0rc1
31
+ """,
31
32
  'click~=8.1.7',
33
+ 'trafaret~=2.1',
32
34
  ),
33
35
  'license': 'MIT',
34
36
  'long_description': """# backend.ai-cli
@@ -74,6 +76,7 @@ You can do the same in `setup.py` as well.
74
76
  },
75
77
  'python_requires': '>=3.11,<3.12',
76
78
  'url': 'https://github.com/lablup/backend.ai',
77
- 'version': '24.03.0dev1',
79
+ 'version': """24.03.0rc1
80
+ """,
78
81
  'zip_safe': False,
79
82
  })
@@ -1 +0,0 @@
1
- 24.03.0dev1
@@ -1,3 +0,0 @@
1
- attrs>=20.3
2
- backend.ai-plugin==24.03.0dev1
3
- click~=8.1.7