remotivelabs-cli 0.0.42__py3-none-any.whl → 0.1.0__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.
- cli/.DS_Store +0 -0
- cli/api/cloud/tokens.py +62 -0
- cli/broker/brokers.py +0 -1
- cli/broker/export.py +4 -4
- cli/broker/lib/broker.py +9 -13
- cli/broker/license_flows.py +1 -1
- cli/broker/scripting.py +2 -1
- cli/broker/signals.py +9 -10
- cli/cloud/auth/cmd.py +37 -13
- cli/cloud/auth/login.py +278 -24
- cli/cloud/auth_tokens.py +319 -12
- cli/cloud/brokers.py +3 -4
- cli/cloud/cloud_cli.py +5 -5
- cli/cloud/configs.py +1 -2
- cli/cloud/organisations.py +101 -2
- cli/cloud/projects.py +5 -6
- cli/cloud/recordings.py +9 -16
- cli/cloud/recordings_playback.py +6 -8
- cli/cloud/sample_recordings.py +2 -3
- cli/cloud/service_account_tokens.py +21 -5
- cli/cloud/service_accounts.py +32 -4
- cli/cloud/storage/cmd.py +1 -1
- cli/cloud/storage/copy.py +3 -4
- cli/connect/connect.py +1 -1
- cli/connect/protopie/protopie.py +12 -14
- cli/errors.py +6 -1
- cli/remotive.py +30 -6
- cli/settings/__init__.py +1 -2
- cli/settings/config_file.py +92 -0
- cli/settings/core.py +188 -45
- cli/settings/migrate_all_token_files.py +74 -0
- cli/settings/migrate_token_file.py +52 -0
- cli/settings/token_file.py +69 -4
- cli/tools/can/can.py +2 -2
- cli/typer/typer_utils.py +18 -1
- cli/utils/__init__.py +0 -0
- cli/{cloud → utils}/rest_helper.py +114 -39
- {remotivelabs_cli-0.0.42.dist-info → remotivelabs_cli-0.1.0.dist-info}/METADATA +6 -4
- remotivelabs_cli-0.1.0.dist-info/RECORD +59 -0
- {remotivelabs_cli-0.0.42.dist-info → remotivelabs_cli-0.1.0.dist-info}/WHEEL +1 -1
- cli/settings/cmd.py +0 -72
- remotivelabs_cli-0.0.42.dist-info/RECORD +0 -54
- {remotivelabs_cli-0.0.42.dist-info → remotivelabs_cli-0.1.0.dist-info}/LICENSE +0 -0
- {remotivelabs_cli-0.0.42.dist-info → remotivelabs_cli-0.1.0.dist-info}/entry_points.txt +0 -0
cli/settings/token_file.py
CHANGED
@@ -3,20 +3,85 @@ from __future__ import annotations
|
|
3
3
|
import dataclasses
|
4
4
|
import json
|
5
5
|
from dataclasses import dataclass
|
6
|
+
from datetime import date, datetime
|
7
|
+
from typing import Any, Literal
|
8
|
+
|
9
|
+
DEFAULT_EMAIL = "unknown@remotivecloud.com"
|
10
|
+
|
11
|
+
TokenType = Literal["authorized_user", "service_account"]
|
12
|
+
|
13
|
+
|
14
|
+
def _parse_date(date_str: str) -> date:
|
15
|
+
normalized = date_str.replace("Z", "+00:00")
|
16
|
+
return datetime.fromisoformat(normalized).date()
|
17
|
+
|
18
|
+
|
19
|
+
def _parse_token_type(token: str) -> TokenType:
|
20
|
+
if token.startswith("pa"):
|
21
|
+
return "authorized_user"
|
22
|
+
if token.startswith("sa"):
|
23
|
+
return "service_account"
|
24
|
+
raise ValueError(f"Unknown token type for token: {token}")
|
25
|
+
|
26
|
+
|
27
|
+
def _from_dict(d: dict[str, Any]) -> TokenFile:
|
28
|
+
if "version" not in d:
|
29
|
+
token_type = _parse_token_type(d["token"])
|
30
|
+
return TokenFile(
|
31
|
+
version="1.0",
|
32
|
+
type=token_type,
|
33
|
+
name=d["name"],
|
34
|
+
token=d["token"],
|
35
|
+
created=_parse_date(d["created"]),
|
36
|
+
expires=_parse_date(d["expires"]),
|
37
|
+
account=TokenFileAccount(email=DEFAULT_EMAIL),
|
38
|
+
)
|
39
|
+
|
40
|
+
account_email = d.get("account", {}).get("email", DEFAULT_EMAIL)
|
41
|
+
return TokenFile(
|
42
|
+
version=d["version"],
|
43
|
+
type=d["type"],
|
44
|
+
name=d["name"],
|
45
|
+
token=d["token"],
|
46
|
+
created=_parse_date(d["created"]),
|
47
|
+
expires=_parse_date(d["expires"]),
|
48
|
+
account=TokenFileAccount(email=account_email),
|
49
|
+
)
|
6
50
|
|
7
51
|
|
8
52
|
def loads(data: str) -> TokenFile:
|
9
|
-
|
10
|
-
return TokenFile(name=d["name"], token=d["token"], created=d["created"], expires=d["expires"])
|
53
|
+
return _from_dict(json.loads(data))
|
11
54
|
|
12
55
|
|
13
56
|
def dumps(token: TokenFile) -> str:
|
14
57
|
return json.dumps(dataclasses.asdict(token), default=str)
|
15
58
|
|
16
59
|
|
60
|
+
@dataclass
|
61
|
+
class TokenFileAccount:
|
62
|
+
email: str
|
63
|
+
|
64
|
+
|
17
65
|
@dataclass
|
18
66
|
class TokenFile:
|
67
|
+
version: str
|
68
|
+
type: TokenType
|
19
69
|
name: str
|
20
70
|
token: str
|
21
|
-
created:
|
22
|
-
expires:
|
71
|
+
created: date
|
72
|
+
expires: date
|
73
|
+
account: TokenFileAccount
|
74
|
+
|
75
|
+
def is_expired(self) -> bool:
|
76
|
+
return datetime.today().date() > self.expires
|
77
|
+
|
78
|
+
def expires_in_days(self) -> int:
|
79
|
+
return (self.expires - datetime.today().date()).days
|
80
|
+
|
81
|
+
@staticmethod
|
82
|
+
def from_json_str(data: str) -> TokenFile:
|
83
|
+
return loads(data)
|
84
|
+
|
85
|
+
@staticmethod
|
86
|
+
def from_dict(data: dict[str, Any]) -> TokenFile:
|
87
|
+
return _from_dict(data)
|
cli/tools/can/can.py
CHANGED
@@ -48,7 +48,7 @@ def convert(
|
|
48
48
|
with can.Logger(out_file) as writer:
|
49
49
|
for msg in reader:
|
50
50
|
writer.on_message_received(msg)
|
51
|
-
except Exception as e:
|
51
|
+
except Exception as e:
|
52
52
|
err_console.print(f":boom: [bold red]Failed to convert file[/bold red]: {e}")
|
53
53
|
|
54
54
|
|
@@ -77,5 +77,5 @@ def validate(
|
|
77
77
|
if print_to_terminal:
|
78
78
|
writer.on_message_received(msg)
|
79
79
|
console.print(f"Successfully verified {in_file}")
|
80
|
-
except Exception as e:
|
80
|
+
except Exception as e:
|
81
81
|
err_console.print(f":boom: [bold red]Failed to convert file[/bold red]: {e}")
|
cli/typer/typer_utils.py
CHANGED
@@ -1,8 +1,25 @@
|
|
1
1
|
from typing import Any
|
2
2
|
|
3
3
|
import typer
|
4
|
+
from click import Context
|
5
|
+
from rich.console import Console
|
6
|
+
from typer.core import TyperGroup
|
7
|
+
|
8
|
+
|
9
|
+
class OrderCommands(TyperGroup):
|
10
|
+
def list_commands(self, _ctx: Context): # type: ignore
|
11
|
+
return list(self.commands)
|
12
|
+
|
13
|
+
|
14
|
+
console = Console()
|
4
15
|
|
5
16
|
|
6
17
|
def create_typer(**kwargs: Any) -> typer.Typer:
|
7
18
|
"""Create a Typer instance with default settings."""
|
8
|
-
return typer.Typer(no_args_is_help=True, **kwargs)
|
19
|
+
# return typer.Typer(no_args_is_help=True, **kwargs)
|
20
|
+
return typer.Typer(cls=OrderCommands, no_args_is_help=True, **kwargs)
|
21
|
+
|
22
|
+
|
23
|
+
def print_padded(label: str, right_text: str, length: int = 30) -> None:
|
24
|
+
padded_label = label.ljust(length) # pad to 30 characters
|
25
|
+
console.print(f"{padded_label} {right_text}")
|
cli/utils/__init__.py
ADDED
File without changes
|
@@ -8,7 +8,7 @@ import shutil
|
|
8
8
|
import sys
|
9
9
|
from importlib.metadata import version
|
10
10
|
from pathlib import Path
|
11
|
-
from typing import Any, BinaryIO, Dict, List, Union, cast
|
11
|
+
from typing import Any, BinaryIO, Dict, List, Optional, Union, cast
|
12
12
|
|
13
13
|
import requests
|
14
14
|
from requests.exceptions import JSONDecodeError
|
@@ -32,10 +32,15 @@ class RestHelper:
|
|
32
32
|
"""Static Class with various helper functions for the rest API"""
|
33
33
|
|
34
34
|
__base_url = "https://cloud.remotivelabs.com"
|
35
|
+
__frontend_url = __base_url
|
35
36
|
__license_server_base_url = "https://license.cloud.remotivelabs.com"
|
36
37
|
|
37
38
|
if "REMOTIVE_CLOUD_BASE_URL" in os.environ:
|
38
39
|
__base_url = os.environ["REMOTIVE_CLOUD_BASE_URL"]
|
40
|
+
__frontend_url = os.environ["REMOTIVE_CLOUD_BASE_URL"]
|
41
|
+
|
42
|
+
if "REMOTIVE_CLOUD_FRONTEND_BASE_URL" in os.environ:
|
43
|
+
__frontend_url = os.environ["REMOTIVE_CLOUD_FRONTEND_BASE_URL"]
|
39
44
|
|
40
45
|
if "cloud-dev" in __base_url:
|
41
46
|
__license_server_base_url = "https://license.cloud-dev.remotivelabs.com"
|
@@ -47,11 +52,14 @@ class RestHelper:
|
|
47
52
|
# token = os.environ["REMOTIVE_CLOUD_AUTH_TOKEN"]
|
48
53
|
# headers = {"Authorization": "Bearer " + token}
|
49
54
|
|
50
|
-
__headers: Dict[str, str] = {}
|
55
|
+
__headers: Dict[str, str] = {"User-Agent": f"remotivelabs-cli {version('remotivelabs-cli')}"}
|
51
56
|
__org: str = ""
|
52
57
|
|
53
58
|
__token: str = ""
|
54
59
|
|
60
|
+
def _cli_version(self) -> str:
|
61
|
+
return ""
|
62
|
+
|
55
63
|
@staticmethod
|
56
64
|
def get_cli_version() -> str:
|
57
65
|
return version("remotivelabs-cli")
|
@@ -60,6 +68,10 @@ class RestHelper:
|
|
60
68
|
def get_base_url() -> str:
|
61
69
|
return RestHelper.__base_url
|
62
70
|
|
71
|
+
@staticmethod
|
72
|
+
def get_base_frontend_url() -> str:
|
73
|
+
return RestHelper.__frontend_url
|
74
|
+
|
63
75
|
@staticmethod
|
64
76
|
def get_license_server_base_url() -> str:
|
65
77
|
return RestHelper.__license_server_base_url
|
@@ -77,41 +89,63 @@ class RestHelper:
|
|
77
89
|
return RestHelper.__token
|
78
90
|
|
79
91
|
@staticmethod
|
80
|
-
def ensure_auth_token() -> None:
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
92
|
+
def ensure_auth_token(quiet: bool = False, access_token: Optional[str] = None) -> None:
|
93
|
+
if "REMOTIVE_CLOUD_ORGANIZATION" not in os.environ:
|
94
|
+
org = settings.get_cli_config().get_active_default_organisation()
|
95
|
+
if org is not None:
|
96
|
+
os.environ["REMOTIVE_CLOUD_ORGANIZATION"] = org
|
97
|
+
|
98
|
+
token = None
|
99
|
+
|
100
|
+
if access_token is None:
|
101
|
+
if "REMOTIVE_CLOUD_ACCESS_TOKEN" in os.environ:
|
102
|
+
token = os.environ["REMOTIVE_CLOUD_ACCESS_TOKEN"]
|
103
|
+
else:
|
104
|
+
try:
|
105
|
+
token = settings.get_active_token()
|
106
|
+
except TokenNotFoundError:
|
107
|
+
if quiet:
|
108
|
+
return
|
109
|
+
ErrorPrinter.print_hint("you are not logged in, please login using [green]remotive cloud auth login[/green]")
|
110
|
+
sys.exit(1)
|
91
111
|
|
92
|
-
RestHelper.__headers["Authorization"] = "Bearer
|
93
|
-
RestHelper.__headers["User-Agent"] = f"remotivelabs-cli {RestHelper.get_cli_version()}"
|
112
|
+
RestHelper.__headers["Authorization"] = f"Bearer {token.strip() if token is not None else access_token}"
|
94
113
|
|
95
114
|
@staticmethod
|
96
|
-
def handle_get(
|
115
|
+
def handle_get( # noqa: PLR0913
|
97
116
|
url: str,
|
98
117
|
params: Any = None,
|
99
118
|
return_response: bool = False,
|
100
119
|
allow_status_codes: List[int] | None = None,
|
101
120
|
progress_label: str = "Fetching...",
|
102
121
|
use_progress_indicator: bool = True,
|
122
|
+
allow_redirects: bool = False,
|
103
123
|
timeout: int = 60,
|
124
|
+
access_token: Optional[str] = None,
|
125
|
+
skip_access_token: bool = False,
|
104
126
|
) -> requests.Response:
|
105
|
-
# pylint: disable=R0913
|
106
127
|
# Returns a Response object if succesfull otherwise None
|
107
128
|
if params is None:
|
108
129
|
params = {}
|
109
|
-
|
130
|
+
if not skip_access_token:
|
131
|
+
RestHelper.ensure_auth_token(access_token=access_token)
|
110
132
|
if use_progress_indicator:
|
111
133
|
with RestHelper.use_progress(progress_label):
|
112
|
-
r = requests.get(
|
134
|
+
r = requests.get(
|
135
|
+
f"{RestHelper.__base_url}{url}",
|
136
|
+
headers=RestHelper.__headers,
|
137
|
+
params=params,
|
138
|
+
timeout=timeout,
|
139
|
+
allow_redirects=allow_redirects,
|
140
|
+
)
|
113
141
|
else:
|
114
|
-
r = requests.get(
|
142
|
+
r = requests.get(
|
143
|
+
f"{RestHelper.__base_url}{url}",
|
144
|
+
headers=RestHelper.__headers,
|
145
|
+
params=params,
|
146
|
+
timeout=timeout,
|
147
|
+
allow_redirects=allow_redirects,
|
148
|
+
)
|
115
149
|
|
116
150
|
if return_response:
|
117
151
|
RestHelper.check_api_result(r, allow_status_codes)
|
@@ -120,27 +154,34 @@ class RestHelper:
|
|
120
154
|
sys.exit(0)
|
121
155
|
|
122
156
|
@staticmethod
|
123
|
-
def has_access(url: str, params: Any = {}) -> bool:
|
124
|
-
RestHelper.ensure_auth_token()
|
157
|
+
def has_access(url: str, params: Any = {}, access_token: Optional[str] = None) -> bool:
|
158
|
+
RestHelper.ensure_auth_token(quiet=True, access_token=access_token)
|
125
159
|
r = requests.get(f"{RestHelper.__base_url}{url}", headers=RestHelper.__headers, params=params, timeout=60)
|
126
|
-
if r.status_code
|
127
|
-
return
|
128
|
-
return
|
160
|
+
if 200 <= r.status_code <= 299:
|
161
|
+
return True
|
162
|
+
return False
|
129
163
|
|
130
164
|
@staticmethod
|
131
165
|
def check_api_result(response: requests.Response, allow_status_codes: List[int] | None = None) -> None:
|
166
|
+
if response.status_code == 426: # CLI upgrade
|
167
|
+
ErrorPrinter.print_hint(response.text)
|
168
|
+
sys.exit(1)
|
132
169
|
if response.status_code > 299:
|
133
170
|
if allow_status_codes is not None and response.status_code in allow_status_codes:
|
134
171
|
return
|
135
172
|
err_console.print(f":boom: [bold red]Got status code[/bold red]: {response.status_code}")
|
136
173
|
if response.status_code == 401:
|
137
|
-
err_console.print("Your token has expired, please login again")
|
174
|
+
err_console.print("Your token is not valid or has expired, please login again or activate another account")
|
138
175
|
else:
|
139
176
|
err_console.print(response.text)
|
140
177
|
sys.exit(1)
|
141
178
|
|
142
179
|
@staticmethod
|
143
180
|
def print_api_result(response: requests.Response) -> None:
|
181
|
+
if response.status_code == 426: # CLI upgrade
|
182
|
+
ErrorPrinter.print_hint(response.text)
|
183
|
+
sys.exit(1)
|
184
|
+
|
144
185
|
if response.status_code >= 200 and response.status_code < 300:
|
145
186
|
if len(response.content) >= 2:
|
146
187
|
try:
|
@@ -151,31 +192,65 @@ class RestHelper:
|
|
151
192
|
else:
|
152
193
|
err_console.print(f":boom: [bold red]Got status code[/bold red]: {response.status_code}")
|
153
194
|
if response.status_code == 401:
|
154
|
-
err_console.print("Your token has expired, please login again")
|
195
|
+
err_console.print("Your token is not valid or has expired, please login again or activate another account")
|
155
196
|
else:
|
156
197
|
err_console.print(response.text)
|
157
198
|
sys.exit(1)
|
158
|
-
# typer.Exit(1) did not work as expected
|
159
199
|
|
160
200
|
@staticmethod
|
161
|
-
def
|
162
|
-
url: str,
|
163
|
-
|
164
|
-
|
201
|
+
def handle_patch( # noqa: PLR0913
|
202
|
+
url: str,
|
203
|
+
params: Any = {},
|
204
|
+
quiet: bool = False,
|
205
|
+
progress_label: str = "Deleting...",
|
206
|
+
access_token: Optional[str] = None,
|
207
|
+
allow_status_codes: Optional[List[int]] = None,
|
208
|
+
) -> requests.Response:
|
209
|
+
if allow_status_codes is None:
|
210
|
+
allow_status_codes = []
|
211
|
+
RestHelper.ensure_auth_token(access_token=access_token)
|
212
|
+
with RestHelper.use_progress(progress_label):
|
213
|
+
r = requests.patch(f"{RestHelper.__base_url}{url}", headers=RestHelper.__headers, params=params, timeout=60)
|
214
|
+
if r.status_code in (200, 204):
|
215
|
+
if not quiet:
|
216
|
+
RestHelper.print_api_result(r)
|
217
|
+
elif r.status_code not in allow_status_codes:
|
218
|
+
RestHelper.print_api_result(r)
|
219
|
+
return r
|
220
|
+
|
221
|
+
@staticmethod
|
222
|
+
def handle_delete( # noqa: PLR0913
|
223
|
+
url: str,
|
224
|
+
params: Any = {},
|
225
|
+
quiet: bool = False,
|
226
|
+
progress_label: str = "Deleting...",
|
227
|
+
access_token: Optional[str] = None,
|
228
|
+
allow_status_codes: Optional[List[int]] = None,
|
229
|
+
) -> requests.Response:
|
230
|
+
if allow_status_codes is None:
|
231
|
+
allow_status_codes = []
|
232
|
+
RestHelper.ensure_auth_token(access_token=access_token)
|
165
233
|
with RestHelper.use_progress(progress_label):
|
166
234
|
r = requests.delete(f"{RestHelper.__base_url}{url}", headers=RestHelper.__headers, params=params, timeout=60)
|
167
235
|
if r.status_code in (200, 204):
|
168
236
|
if not quiet:
|
169
237
|
RestHelper.print_api_result(r)
|
170
|
-
|
238
|
+
elif r.status_code not in allow_status_codes:
|
171
239
|
RestHelper.print_api_result(r)
|
240
|
+
return r
|
172
241
|
|
173
242
|
@staticmethod
|
174
|
-
def handle_post( #
|
175
|
-
url: str,
|
243
|
+
def handle_post( # noqa: PLR0913
|
244
|
+
url: str,
|
245
|
+
body: Any = None,
|
246
|
+
params: Any = {},
|
247
|
+
progress_label: str = "Processing...",
|
248
|
+
return_response: bool = False,
|
249
|
+
access_token: Optional[str] = None,
|
176
250
|
) -> requests.Response:
|
177
251
|
# Returns a Response object if succesfull otherwise, None
|
178
|
-
|
252
|
+
|
253
|
+
RestHelper.ensure_auth_token(access_token=access_token)
|
179
254
|
RestHelper.__headers["content-type"] = "application/json"
|
180
255
|
|
181
256
|
with RestHelper.use_progress(progress_label):
|
@@ -189,7 +264,7 @@ class RestHelper:
|
|
189
264
|
sys.exit(0)
|
190
265
|
|
191
266
|
@staticmethod
|
192
|
-
def handle_put(url: str, body: Any = None, params: Any = {}, return_response: bool = False) -> requests.Response | None:
|
267
|
+
def handle_put(url: str, body: Any = None, params: Any = {}, return_response: bool = False) -> requests.Response | None:
|
193
268
|
# Returns a Response object if succesfull otherwise, None
|
194
269
|
RestHelper.ensure_auth_token()
|
195
270
|
RestHelper.__headers["content-type"] = "application/json"
|
@@ -243,8 +318,8 @@ class RestHelper:
|
|
243
318
|
return None
|
244
319
|
|
245
320
|
@staticmethod
|
246
|
-
def use_progress(label: str) -> Progress:
|
247
|
-
p = Progress(SpinnerColumn(), TextColumn("[progress.description]{task.description}"), transient=
|
321
|
+
def use_progress(label: str, transient: bool = True) -> Progress:
|
322
|
+
p = Progress(SpinnerColumn(), TextColumn("[progress.description]{task.description}"), transient=transient)
|
248
323
|
p.add_task(label, total=1)
|
249
324
|
return p
|
250
325
|
|
@@ -1,16 +1,18 @@
|
|
1
|
-
Metadata-Version: 2.
|
1
|
+
Metadata-Version: 2.3
|
2
2
|
Name: remotivelabs-cli
|
3
|
-
Version: 0.0
|
3
|
+
Version: 0.1.0
|
4
4
|
Summary: CLI for operating RemotiveCloud and RemotiveBroker
|
5
5
|
Author: Johan Rask
|
6
6
|
Author-email: johan.rask@remotivelabs.com
|
7
|
-
Requires-Python: >=3.
|
7
|
+
Requires-Python: >=3.9,<4
|
8
8
|
Classifier: Programming Language :: Python :: 3
|
9
|
-
Classifier: Programming Language :: Python :: 3.8
|
10
9
|
Classifier: Programming Language :: Python :: 3.9
|
11
10
|
Classifier: Programming Language :: Python :: 3.10
|
12
11
|
Classifier: Programming Language :: Python :: 3.11
|
13
12
|
Classifier: Programming Language :: Python :: 3.12
|
13
|
+
Classifier: Programming Language :: Python :: 3.13
|
14
|
+
Requires-Dist: click (<8.2.0)
|
15
|
+
Requires-Dist: dacite (>=1.9.2,<2.0.0)
|
14
16
|
Requires-Dist: grpc-stubs (>=1.53.0.5)
|
15
17
|
Requires-Dist: mypy-protobuf (>=3.0.0)
|
16
18
|
Requires-Dist: plotext (>=5.2,<6.0)
|
@@ -0,0 +1,59 @@
|
|
1
|
+
cli/.DS_Store,sha256=7HTaExsH9zU3sluA0MFtZuyzNmSnUmH2Sh09uoek84E,8196
|
2
|
+
cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
3
|
+
cli/api/cloud/tokens.py,sha256=3UKfVM3NvZX_ynpPAXZ_cnrPAIIgg0vA1FuOzj8TV2o,1631
|
4
|
+
cli/broker/brokers.py,sha256=lfO0oAuOwLiJkuNIusXCnOGrxEKGvQjy75LMY9jP5-Y,3234
|
5
|
+
cli/broker/export.py,sha256=rr6OGZmkbqVUljy-gluC2CeRDKbI_p41EhleT3lcgXQ,4481
|
6
|
+
cli/broker/files.py,sha256=JMpyBYfqVX_ppIChDcUuWvCDIQHC8YI6IsljyIL0NZ8,4212
|
7
|
+
cli/broker/lib/__about__.py,sha256=xnZ5V6ZcHW9dhWLWdMzVjYJbEnMKpeXm0_S_mbNzypE,141
|
8
|
+
cli/broker/lib/broker.py,sha256=Qu6OuKt0P4aFPRSbmcdXUly9iQrnDgUcHTjVJzahTCQ,25006
|
9
|
+
cli/broker/license_flows.py,sha256=du5SSAdzr2VZeORWoAgbYrfi-mpnDUQfIVpfAJK6CSM,7216
|
10
|
+
cli/broker/licenses.py,sha256=jIuLB2qBGflzSjm952CBnErpzs7iIkmEgx9L8GDAPNc,4021
|
11
|
+
cli/broker/playback.py,sha256=fO-ZvzmB3ZzanmD1L09PeKkabx35uKsELMM-h-5brSE,4023
|
12
|
+
cli/broker/record.py,sha256=rVjvyWRSWNFtthZZkZeZZGvZdmhDB_qmYcrCocCJxY4,1445
|
13
|
+
cli/broker/scripting.py,sha256=LFLdaBNxe2sfpcxhDmRlAbEorjL3SJZNK-zEdLQ9ySU,3854
|
14
|
+
cli/broker/signals.py,sha256=MFj_bOLIxHY1v3XPkKk6n8U3JLaY8nrXHahRQaVse6s,8207
|
15
|
+
cli/cloud/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
16
|
+
cli/cloud/auth/__init__.py,sha256=MtQ01-n8CgZb9Y_SvxwZUgj44Yo0dFAU3_XwhQiUYtw,54
|
17
|
+
cli/cloud/auth/cmd.py,sha256=aOvbrzNb7moClgmde25T0coBs8Ge696xUB_w6qfvN8I,2920
|
18
|
+
cli/cloud/auth/login.py,sha256=kaUxKfXXk392s2mMM8d-5wuhWuIqVNK6PKLSu-pxMbw,11444
|
19
|
+
cli/cloud/auth_tokens.py,sha256=XHXrCwgK_akrCbFxcxtDr7GDM9cd-T_s40PrRovY4Lk,12344
|
20
|
+
cli/cloud/brokers.py,sha256=QTA9bmaK06LKEccF6IBgWBonC4VFrKwFQBsACX_IzYw,3896
|
21
|
+
cli/cloud/cloud_cli.py,sha256=q-oiaLcKC-BRamXfIFGn-BskRmJ3utA7-tI39lSs3Cs,1309
|
22
|
+
cli/cloud/configs.py,sha256=uv46nUoGXOr99smQHahv_ageDv6bGYfUnlRlxcS5D9A,5125
|
23
|
+
cli/cloud/organisations.py,sha256=QBD2RnCbpZ9XQrTIcvD74o321JHNnKxDleKlYmSZEuI,4116
|
24
|
+
cli/cloud/projects.py,sha256=ecn5Y8UKhgYnHSJQACUk1GNZt9EF8ug4B-6MCr8rZqM,1487
|
25
|
+
cli/cloud/recordings.py,sha256=B0XOj8LIm3hBqBzVKPLPvPUCXCKZBTEISssrijK481w,24855
|
26
|
+
cli/cloud/recordings_playback.py,sha256=XZoVyujufMQFN2v_Nwsf8tOqn61yLEpAf2z_u5uhXik,11532
|
27
|
+
cli/cloud/resumable_upload.py,sha256=8lEIdncJZoTZzNsQVHH3gm_GunxEmN5JbmWX7awy3p4,3713
|
28
|
+
cli/cloud/sample_recordings.py,sha256=RmuT-a2iMwGj3LXVcPkV5l66uFcf7nyWyJciUjnYkk4,721
|
29
|
+
cli/cloud/service_account_tokens.py,sha256=lZHrja2hIyeXGTNGsxaZ_NlS_iXcyWR_h62H4OYeTMk,2783
|
30
|
+
cli/cloud/service_accounts.py,sha256=AiktZW5QTbT6sAPJi4ubETOqbBDAIt4LOE-TZmIiIkk,2586
|
31
|
+
cli/cloud/storage/__init__.py,sha256=ijl9WwU5D4oASbwrFKJurYsBUyzwZCOhcdTQYj-ZSeM,159
|
32
|
+
cli/cloud/storage/cmd.py,sha256=UOPpzZeqtqAD2qAbFRGHnbpliq6T_8phKQSxU0EeaqI,2970
|
33
|
+
cli/cloud/storage/copy.py,sha256=tPvRcKFhzxbBhjvQ6ZGMe81hksfYwbn7dEgrjpYaC0Q,3237
|
34
|
+
cli/cloud/storage/uri_or_path.py,sha256=DLlyr0RAV-DRlL2C36U-jvUqwiLIlkw7c3mJ7SSGMdI,1158
|
35
|
+
cli/cloud/uri.py,sha256=QZCus--KJQlVwGCOzZqiglvj8VvSRKxfVvN33Pilgyg,3616
|
36
|
+
cli/connect/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
37
|
+
cli/connect/connect.py,sha256=SH2DNTTVLu2dNpk6xIah1-KJZAqrK_7Skt8RKp8Mjh8,4231
|
38
|
+
cli/connect/protopie/protopie.py,sha256=ElmrGaV0ivb85wo0gLzCAXZhmSmIDASaCVlF1iQblLI,6532
|
39
|
+
cli/errors.py,sha256=_P-qpayY06qgLA7wvoDFsyMaTfo_zjNY--fgHPAuhrs,1658
|
40
|
+
cli/remotive.py,sha256=PsxR3Hhp3zhj-A06sqvtSkmXwv9moWHT_ify8Vg5xQA,2756
|
41
|
+
cli/settings/__init__.py,sha256=5ZRq04PHp3WU_5e7mGwWUoFYUPWfnnS16yF45wUv7mY,248
|
42
|
+
cli/settings/config_file.py,sha256=6WHlJT74aQvqc5elcW1FDafcG0NttYvPawmArN5H2MQ,2869
|
43
|
+
cli/settings/core.py,sha256=vRS_3JZDKRMGMa65C3LT178BCUcZ2RAlp2knn158CA4,15669
|
44
|
+
cli/settings/migrate_all_token_files.py,sha256=7kvHbpP4BtILJ8kPtb_bFnTnBYX9isZ4rwB5lfnEkbA,2722
|
45
|
+
cli/settings/migrate_token_file.py,sha256=Fp7Z_lNqSdoWY05TYwFW2QH8q9QhmB2TYSok6hV1Mic,1530
|
46
|
+
cli/settings/token_file.py,sha256=KISVaSVV2pzfduCtJYUtCLtJa3htrpP4_qTODp5IhW8,2210
|
47
|
+
cli/tools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
48
|
+
cli/tools/can/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
49
|
+
cli/tools/can/can.py,sha256=TtP5w8vb0QG4ObNhkWIDpRMdNelirFffoc_lFZy8ePM,2260
|
50
|
+
cli/tools/tools.py,sha256=jhLfrFDqkmWV3eBAzNwBf6WgDGrz7sOhgVCia36Twn8,232
|
51
|
+
cli/typer/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
52
|
+
cli/typer/typer_utils.py,sha256=8SkvG9aKkfK9fTRsLD9pOBtWn9XSwtOXWg2RAk9FhOI,708
|
53
|
+
cli/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
54
|
+
cli/utils/rest_helper.py,sha256=b_FJY6MxnFSqo11qaHxkBFHfVlKf7Zj28Uxv9Oj7XY4,14141
|
55
|
+
remotivelabs_cli-0.1.0.dist-info/LICENSE,sha256=qDPP_yfuv1fF-u7EfexN-cN3M8aFgGVndGhGLovLKz0,608
|
56
|
+
remotivelabs_cli-0.1.0.dist-info/METADATA,sha256=fg0RiyvpN9JCiNfgzVvg4a2ynEyZvSsgcrc6w2xM9II,1428
|
57
|
+
remotivelabs_cli-0.1.0.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
|
58
|
+
remotivelabs_cli-0.1.0.dist-info/entry_points.txt,sha256=lvDhPgagLqW_KTnLPCwKSqfYlEp-1uYVosRiPjsVj10,45
|
59
|
+
remotivelabs_cli-0.1.0.dist-info/RECORD,,
|
cli/settings/cmd.py
DELETED
@@ -1,72 +0,0 @@
|
|
1
|
-
import typer
|
2
|
-
|
3
|
-
from cli.errors import ErrorPrinter
|
4
|
-
from cli.settings.core import TokenNotFoundError, settings
|
5
|
-
from cli.typer import typer_utils
|
6
|
-
|
7
|
-
app = typer_utils.create_typer()
|
8
|
-
|
9
|
-
|
10
|
-
@app.command()
|
11
|
-
def describe(file: str = typer.Argument(help="Token name or file path")) -> None:
|
12
|
-
"""
|
13
|
-
Show contents of specified access token file
|
14
|
-
"""
|
15
|
-
try:
|
16
|
-
print(settings.get_token_file(file))
|
17
|
-
except TokenNotFoundError:
|
18
|
-
ErrorPrinter.print_generic_error(f"Token file {file} not found")
|
19
|
-
|
20
|
-
|
21
|
-
@app.command()
|
22
|
-
def activate(file: str = typer.Argument(..., help="Token name or file path")) -> None:
|
23
|
-
"""
|
24
|
-
Activate a access token file to be used for authentication.
|
25
|
-
|
26
|
-
This will be used as the current access token in all subsequent requests. This would
|
27
|
-
be the same as login with a browser.
|
28
|
-
"""
|
29
|
-
try:
|
30
|
-
settings.activate_token(file)
|
31
|
-
except FileNotFoundError as e:
|
32
|
-
print(f"File could not be found: {e}")
|
33
|
-
|
34
|
-
|
35
|
-
@app.command(name="list-personal-tokens")
|
36
|
-
def list_pats() -> None:
|
37
|
-
"""
|
38
|
-
List personal access token files in remotivelabs config directory
|
39
|
-
"""
|
40
|
-
pats = settings.list_personal_tokens()
|
41
|
-
for pat in pats:
|
42
|
-
print(pat.name)
|
43
|
-
|
44
|
-
|
45
|
-
@app.command(name="list-personal-tokens-files")
|
46
|
-
def list_pats_files() -> None:
|
47
|
-
"""
|
48
|
-
List personal access token files in remotivelabs config directory
|
49
|
-
"""
|
50
|
-
personal_files = settings.list_personal_token_files()
|
51
|
-
for file in personal_files:
|
52
|
-
print(file)
|
53
|
-
|
54
|
-
|
55
|
-
@app.command(name="list-service-account-tokens")
|
56
|
-
def list_sats() -> None:
|
57
|
-
"""
|
58
|
-
List service account access token files in remotivelabs config directory
|
59
|
-
"""
|
60
|
-
sats = settings.list_service_account_tokens()
|
61
|
-
for sat in sats:
|
62
|
-
print(sat.name)
|
63
|
-
|
64
|
-
|
65
|
-
@app.command(name="list-service-account-tokens-files")
|
66
|
-
def list_sats_files() -> None:
|
67
|
-
"""
|
68
|
-
List service account access token files in remotivelabs config directory
|
69
|
-
"""
|
70
|
-
service_account_files = settings.list_service_account_token_files()
|
71
|
-
for file in service_account_files:
|
72
|
-
print(file)
|
@@ -1,54 +0,0 @@
|
|
1
|
-
cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
2
|
-
cli/broker/brokers.py,sha256=xpwC6S5wCVn_9MOXa12Z-CbRvacjXETU0bqxOlFGKjo,3245
|
3
|
-
cli/broker/export.py,sha256=rXWPP8JZgWt48l_sVZu5oJ7lEKT6Q1NnR5b493GZ50Q,4476
|
4
|
-
cli/broker/files.py,sha256=JMpyBYfqVX_ppIChDcUuWvCDIQHC8YI6IsljyIL0NZ8,4212
|
5
|
-
cli/broker/lib/__about__.py,sha256=xnZ5V6ZcHW9dhWLWdMzVjYJbEnMKpeXm0_S_mbNzypE,141
|
6
|
-
cli/broker/lib/broker.py,sha256=HbGo83j6ipaol0uJ93Me78pOPjy7p8PUjYT9xZmRT-w,25086
|
7
|
-
cli/broker/license_flows.py,sha256=qJplaeugkUiypFGPdEIl5Asqlf7W3geJ-wU-QbYMP_8,7216
|
8
|
-
cli/broker/licenses.py,sha256=jIuLB2qBGflzSjm952CBnErpzs7iIkmEgx9L8GDAPNc,4021
|
9
|
-
cli/broker/playback.py,sha256=fO-ZvzmB3ZzanmD1L09PeKkabx35uKsELMM-h-5brSE,4023
|
10
|
-
cli/broker/record.py,sha256=rVjvyWRSWNFtthZZkZeZZGvZdmhDB_qmYcrCocCJxY4,1445
|
11
|
-
cli/broker/scripting.py,sha256=RExHSruSyL8MjEhZHj9SVKi3z5OuSWwiz44hc9X3hiY,3839
|
12
|
-
cli/broker/signals.py,sha256=1f3pwMBbhxg_x4ktGR9eivNDPJY678CpTBrjXbQaItg,8193
|
13
|
-
cli/cloud/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
14
|
-
cli/cloud/auth/__init__.py,sha256=MtQ01-n8CgZb9Y_SvxwZUgj44Yo0dFAU3_XwhQiUYtw,54
|
15
|
-
cli/cloud/auth/cmd.py,sha256=rdM1Am0E5AcErn0s35x0KL5ys_dGSGaIE7nw0SNtF-0,1655
|
16
|
-
cli/cloud/auth/login.py,sha256=Yrir9ThKJ7sqL4AsEivXxMKjP7QevEGxcm3f2BPUqFg,1898
|
17
|
-
cli/cloud/auth_tokens.py,sha256=xTdL_wHVnOq1hW45XU9iDvQWW7ISDuf5RrDgVilg4-U,1263
|
18
|
-
cli/cloud/brokers.py,sha256=TzUfd2PBfF3vDyTjZ4fMv8ndA4_37IUgOuZHgGHGSEE,3938
|
19
|
-
cli/cloud/cloud_cli.py,sha256=a-LhunHPRPZkxaXQJ0evOYCVXZRYY_qzM6GJG75SjkY,1309
|
20
|
-
cli/cloud/configs.py,sha256=y7uu9IRJjspSpxREvwRNNfx0N1ypstElaqtpt9tepgY,5117
|
21
|
-
cli/cloud/organisations.py,sha256=FJvNjsQFTSqvHs8xWkyVaep1rlYmf1X8Im26Zbxb9iE,432
|
22
|
-
cli/cloud/projects.py,sha256=gXvlaGER3zxBwvjdO3lOa6Fl1xHfQHVCaPdpUNi7G3k,1479
|
23
|
-
cli/cloud/recordings.py,sha256=QrgXJC4csC73Gau-dV_YgL0EZaUzFbc9Nkz_qZHrp70,25067
|
24
|
-
cli/cloud/recordings_playback.py,sha256=dRciL4Oiki6laxRiN8CLiJbsjdjcNpUbv8wxaP91_PA,11614
|
25
|
-
cli/cloud/rest_helper.py,sha256=mm7kMPDVapJPL1X-xsn7wpY3wuOuawgzJgij5iKEaiE,11448
|
26
|
-
cli/cloud/resumable_upload.py,sha256=8lEIdncJZoTZzNsQVHH3gm_GunxEmN5JbmWX7awy3p4,3713
|
27
|
-
cli/cloud/sample_recordings.py,sha256=zHfzpo-YxuBaor95PeVJrbBYyPBXS5zOBf2j0lYnT9Q,738
|
28
|
-
cli/cloud/service_account_tokens.py,sha256=7rwR8UoqG3Y1aPqf0lDcwpYd9X3sM7J9qTmL30iUBsY,1814
|
29
|
-
cli/cloud/service_accounts.py,sha256=BmliX2w3LBoZoZ8fCR0fP3ph945YPIZBAb8Y13oWZuw,1707
|
30
|
-
cli/cloud/storage/__init__.py,sha256=ijl9WwU5D4oASbwrFKJurYsBUyzwZCOhcdTQYj-ZSeM,159
|
31
|
-
cli/cloud/storage/cmd.py,sha256=3j_SbM0Pvh7QklJPfF8DMhj-VpohAf6mcgO0TaaSuHc,2970
|
32
|
-
cli/cloud/storage/copy.py,sha256=4FDBNZVcHKxDI9vU8qawOBcWNYobZu8RdtPUHZsY7iA,3253
|
33
|
-
cli/cloud/storage/uri_or_path.py,sha256=DLlyr0RAV-DRlL2C36U-jvUqwiLIlkw7c3mJ7SSGMdI,1158
|
34
|
-
cli/cloud/uri.py,sha256=QZCus--KJQlVwGCOzZqiglvj8VvSRKxfVvN33Pilgyg,3616
|
35
|
-
cli/connect/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
36
|
-
cli/connect/connect.py,sha256=ygpsd3ZMXQe7wZeJ_E1TBkRDgTxr9r5V7XeoUO_-68w,4239
|
37
|
-
cli/connect/protopie/protopie.py,sha256=GRFN4P5zxWcgwuIwRKUeJ3ie0HqtHUxN7f6dsWPCfBc,6524
|
38
|
-
cli/errors.py,sha256=8_BcTPX3mrPFDQJKKBg6ERjs6HSOiewrY86K1Jays74,1495
|
39
|
-
cli/remotive.py,sha256=B9wCk1jeAd21VgWDW4ntziuwhFk1J5I4wr903l1AZ58,1951
|
40
|
-
cli/settings/__init__.py,sha256=4Mj9DFvRBN0LKn6PPLrb-BmuObP707IYeRmg7t7aycg,288
|
41
|
-
cli/settings/cmd.py,sha256=1riCR5oCjAtNEnyE9wnit1NPa-BJJtuFMUDMMtX-b7E,2039
|
42
|
-
cli/settings/core.py,sha256=o9SDCiqYfihHbiepFebpEB5vEMW656vngyjCkXJaaeQ,9209
|
43
|
-
cli/settings/token_file.py,sha256=UUSbnm6zrPS2HJmbyLzfoKWjmHVOh3IjiwDvLPCoyXc,455
|
44
|
-
cli/tools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
45
|
-
cli/tools/can/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
46
|
-
cli/tools/can/can.py,sha256=42BwsIOx9NUPkp_rB-0MDqL1tCpeqYVOgWzpixm5ykk,2310
|
47
|
-
cli/tools/tools.py,sha256=jhLfrFDqkmWV3eBAzNwBf6WgDGrz7sOhgVCia36Twn8,232
|
48
|
-
cli/typer/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
49
|
-
cli/typer/typer_utils.py,sha256=DmGxdIo0_iK_DYJrZvpFT-tEaQZT1cJtrFR-5VmF_jo,199
|
50
|
-
remotivelabs_cli-0.0.42.dist-info/LICENSE,sha256=qDPP_yfuv1fF-u7EfexN-cN3M8aFgGVndGhGLovLKz0,608
|
51
|
-
remotivelabs_cli-0.0.42.dist-info/METADATA,sha256=gIn4oB_y8v29-ytAQXcHvfdUfGP-E04atfh8GHphRRA,1359
|
52
|
-
remotivelabs_cli-0.0.42.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
53
|
-
remotivelabs_cli-0.0.42.dist-info/entry_points.txt,sha256=lvDhPgagLqW_KTnLPCwKSqfYlEp-1uYVosRiPjsVj10,45
|
54
|
-
remotivelabs_cli-0.0.42.dist-info/RECORD,,
|
File without changes
|
File without changes
|