remotivelabs-cli 0.0.26__py3-none-any.whl → 0.0.28__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/broker/lib/broker.py +24 -3
- cli/broker/signals.py +9 -1
- cli/cloud/auth_tokens.py +38 -4
- cli/cloud/cloud_cli.py +2 -16
- cli/cloud/configs.py +9 -0
- cli/cloud/filestorage.py +20 -5
- cli/cloud/organisations.py +30 -0
- cli/cloud/projects.py +2 -2
- cli/cloud/recordings.py +22 -10
- cli/cloud/resumable_upload.py +24 -1
- {remotivelabs_cli-0.0.26.dist-info → remotivelabs_cli-0.0.28.dist-info}/METADATA +1 -1
- {remotivelabs_cli-0.0.26.dist-info → remotivelabs_cli-0.0.28.dist-info}/RECORD +15 -14
- {remotivelabs_cli-0.0.26.dist-info → remotivelabs_cli-0.0.28.dist-info}/LICENSE +0 -0
- {remotivelabs_cli-0.0.26.dist-info → remotivelabs_cli-0.0.28.dist-info}/WHEEL +0 -0
- {remotivelabs_cli-0.0.26.dist-info → remotivelabs_cli-0.0.28.dist-info}/entry_points.txt +0 -0
cli/broker/lib/broker.py
CHANGED
@@ -360,7 +360,7 @@ class Broker:
|
|
360
360
|
namespaces.append(network_info.namespace.name)
|
361
361
|
return namespaces
|
362
362
|
|
363
|
-
def list_signal_names(self) -> List[Dict[str,
|
363
|
+
def list_signal_names(self) -> List[Dict[str, Any]]:
|
364
364
|
# Lists available signals
|
365
365
|
configuration = self.system_stub.GetConfiguration(br.common_pb2.Empty())
|
366
366
|
|
@@ -369,9 +369,30 @@ class Broker:
|
|
369
369
|
res = self.system_stub.ListSignals(network_info.namespace)
|
370
370
|
for finfo in res.frame:
|
371
371
|
# f: br.common_pb2.FrameInfo = finfo
|
372
|
-
|
372
|
+
receivers = []
|
373
373
|
for sinfo in finfo.childInfo:
|
374
|
-
|
374
|
+
rec = list(map(lambda r: r, sinfo.metaData.receiver))
|
375
|
+
receivers.extend(rec)
|
376
|
+
signal_names.append(
|
377
|
+
{
|
378
|
+
"signal": sinfo.id.name,
|
379
|
+
"namespace": network_info.namespace.name,
|
380
|
+
"receivers": rec,
|
381
|
+
"min": sinfo.metaData.min,
|
382
|
+
"max": sinfo.metaData.max,
|
383
|
+
}
|
384
|
+
)
|
385
|
+
|
386
|
+
signal_names.append(
|
387
|
+
{
|
388
|
+
"signal": finfo.signalInfo.id.name,
|
389
|
+
"namespace": network_info.namespace.name,
|
390
|
+
"senders": list(map(lambda s: s, finfo.signalInfo.metaData.sender)),
|
391
|
+
"receivers": list(set(receivers)),
|
392
|
+
"cycletime": finfo.signalInfo.metaData.cycleTime,
|
393
|
+
}
|
394
|
+
)
|
395
|
+
|
375
396
|
return signal_names
|
376
397
|
|
377
398
|
def subscribe_on_script(
|
cli/broker/signals.py
CHANGED
@@ -30,7 +30,15 @@ class Signals(TypedDict):
|
|
30
30
|
signal_values: Dict[Any, Any] = {}
|
31
31
|
|
32
32
|
|
33
|
-
@app.command(help="List
|
33
|
+
@app.command(name="list", help="List frame and signal metadata on broker")
|
34
|
+
def list_signals(
|
35
|
+
url: str = typer.Option(..., help="Broker URL", envvar="REMOTIVE_BROKER_URL"),
|
36
|
+
api_key: str = typer.Option(None, help="Cloud Broker API-KEY or access token", envvar="REMOTIVE_BROKER_API_KEY"),
|
37
|
+
) -> None:
|
38
|
+
signal_names(url, api_key)
|
39
|
+
|
40
|
+
|
41
|
+
@app.command(help="List signals names on broker", deprecated=True)
|
34
42
|
def signal_names(
|
35
43
|
url: str = typer.Option(..., help="Broker URL", envvar="REMOTIVE_BROKER_URL"),
|
36
44
|
api_key: str = typer.Option(None, help="Cloud Broker API-KEY or access token", envvar="REMOTIVE_BROKER_API_KEY"),
|
cli/cloud/auth_tokens.py
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
import json
|
2
2
|
import os
|
3
3
|
import sys
|
4
|
+
from json.decoder import JSONDecodeError
|
4
5
|
from pathlib import Path
|
5
6
|
|
6
7
|
import typer
|
@@ -42,14 +43,38 @@ def list_personal_access_tokens() -> None:
|
|
42
43
|
Rest.handle_get("/api/me/keys")
|
43
44
|
|
44
45
|
|
45
|
-
@app.command(name="revoke"
|
46
|
-
def revoke(
|
46
|
+
@app.command(name="revoke")
|
47
|
+
def revoke(name_or_file: str = typer.Argument(help="Name or file path of the access token to revoke")) -> None:
|
48
|
+
"""
|
49
|
+
Revoke an access token by token name or path to a file containing that token
|
50
|
+
|
51
|
+
Name is found in the json file
|
52
|
+
```
|
53
|
+
{
|
54
|
+
"expires": "2034-07-31",
|
55
|
+
"token": "xxx",
|
56
|
+
"created": "2024-07-31T09:18:50.406+02:00",
|
57
|
+
"name": "token_name"
|
58
|
+
}
|
59
|
+
```
|
60
|
+
"""
|
61
|
+
name = name_or_file
|
62
|
+
if "." in name_or_file:
|
63
|
+
json_str = read_file(name_or_file)
|
64
|
+
try:
|
65
|
+
name = json.loads(json_str)["name"]
|
66
|
+
except JSONDecodeError:
|
67
|
+
sys.stderr.write("Failed to parse json, make sure its a correct access token file\n")
|
68
|
+
sys.exit(1)
|
69
|
+
except KeyError:
|
70
|
+
sys.stderr.write("Json does not contain a name property, make sure its a correct access token file\n")
|
71
|
+
sys.exit(1)
|
47
72
|
Rest.ensure_auth_token()
|
48
73
|
Rest.handle_delete(f"/api/me/keys/{name}")
|
49
74
|
|
50
75
|
|
51
76
|
@app.command()
|
52
|
-
def describe(file: str = typer.
|
77
|
+
def describe(file: str = typer.Argument(help="File name")) -> None:
|
53
78
|
"""
|
54
79
|
Show contents of specified access token file
|
55
80
|
"""
|
@@ -92,7 +117,16 @@ def list_files() -> None:
|
|
92
117
|
|
93
118
|
|
94
119
|
def read_file(file: str) -> str:
|
95
|
-
|
120
|
+
"""
|
121
|
+
Reads a file using file path or if that does not exist check under ~/.config/.remotive
|
122
|
+
"""
|
123
|
+
path = file
|
124
|
+
if not Path(file).exists():
|
125
|
+
path = str(Path.home()) + f"/.config/.remotive/{file}"
|
126
|
+
if not Path(path).exists():
|
127
|
+
sys.stderr.write(f"Failed to find file using {file} or {path}\n")
|
128
|
+
sys.exit(1)
|
129
|
+
with open(path, "r", encoding="utf8") as f:
|
96
130
|
token = f.read()
|
97
131
|
f.close()
|
98
132
|
return token
|
cli/cloud/cloud_cli.py
CHANGED
@@ -1,10 +1,8 @@
|
|
1
|
-
import json
|
2
|
-
|
3
1
|
import typer
|
4
2
|
|
5
3
|
from cli.cloud.rest_helper import RestHelper
|
6
4
|
|
7
|
-
from . import auth, brokers, configs, filestorage, projects, recordings, sample_recordings, service_accounts
|
5
|
+
from . import auth, brokers, configs, filestorage, organisations, projects, recordings, sample_recordings, service_accounts
|
8
6
|
|
9
7
|
app = typer.Typer()
|
10
8
|
|
@@ -17,19 +15,7 @@ def licenses(
|
|
17
15
|
RestHelper.handle_get(f"/api/bu/{organisation}/licenses", {"filter": filter_option})
|
18
16
|
|
19
17
|
|
20
|
-
|
21
|
-
def organisations() -> None:
|
22
|
-
r = RestHelper.handle_get("/api/home", return_response=True)
|
23
|
-
if r is None:
|
24
|
-
return
|
25
|
-
if r.status_code == 200:
|
26
|
-
j = list(map(lambda x: x["billableUnitUser"]["billableUnit"]["uid"], r.json()))
|
27
|
-
print(json.dumps(j))
|
28
|
-
else:
|
29
|
-
print(f"Got status code: {r.status_code}")
|
30
|
-
print(r.text)
|
31
|
-
|
32
|
-
|
18
|
+
app.add_typer(organisations.app, name="organisations", help="Manage organisations")
|
33
19
|
app.add_typer(projects.app, name="projects", help="Manage projects")
|
34
20
|
app.add_typer(auth.app, name="auth")
|
35
21
|
app.add_typer(brokers.app, name="brokers", help="Manage cloud broker lifecycle")
|
cli/cloud/configs.py
CHANGED
@@ -14,6 +14,9 @@ app = typer.Typer()
|
|
14
14
|
|
15
15
|
@app.command("list")
|
16
16
|
def list_signal_databases(project: str = typer.Option(..., help="Project ID", envvar="REMOTIVE_CLOUD_PROJECT")) -> None:
|
17
|
+
"""
|
18
|
+
List available signal databases in project
|
19
|
+
"""
|
17
20
|
Rest.handle_get(f"/api/project/{project}/files/config")
|
18
21
|
|
19
22
|
|
@@ -22,6 +25,9 @@ def delete(
|
|
22
25
|
signal_db_file: str = typer.Argument("", help="Signal database file"),
|
23
26
|
project: str = typer.Option(..., help="Project ID", envvar="REMOTIVE_CLOUD_PROJECT"),
|
24
27
|
) -> None:
|
28
|
+
"""
|
29
|
+
Deletes the specified signal database
|
30
|
+
"""
|
25
31
|
Rest.handle_delete(f"/api/project/{project}/files/config/{signal_db_file}")
|
26
32
|
|
27
33
|
|
@@ -54,6 +60,9 @@ def download(
|
|
54
60
|
signal_db_file: str = typer.Argument("", help="Signal database file"),
|
55
61
|
project: str = typer.Option(..., help="Project ID", envvar="REMOTIVE_CLOUD_PROJECT"),
|
56
62
|
) -> None:
|
63
|
+
"""
|
64
|
+
Downloads the specified signal database to disk
|
65
|
+
"""
|
57
66
|
with Progress(
|
58
67
|
SpinnerColumn(),
|
59
68
|
TextColumn("[progress.description]{task.description}"),
|
cli/cloud/filestorage.py
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
|
1
3
|
import os.path
|
2
4
|
import sys
|
3
5
|
from pathlib import Path
|
@@ -96,11 +98,24 @@ def copy_file( # noqa: C901 # type: ignore[too-many-branches] # pylint: disabl
|
|
96
98
|
if source.startswith("rcs://"):
|
97
99
|
__copy_to_local(source=source, dest=dest, project=project)
|
98
100
|
else:
|
99
|
-
|
101
|
+
path = Path(source)
|
102
|
+
if path.is_dir():
|
103
|
+
print("is dir")
|
104
|
+
for file_path in path.rglob("*"):
|
105
|
+
if file_path.is_file():
|
106
|
+
print(file_path)
|
107
|
+
__copy_to_remote(source=source, dest=dest, project=project)
|
108
|
+
sys.exit(1)
|
109
|
+
else:
|
110
|
+
__copy_to_remote(source=source, dest=dest, project=project)
|
100
111
|
|
101
112
|
|
102
113
|
def __copy_to_remote(source: str, dest: str, project: str) -> None:
|
103
114
|
path = Path(source)
|
115
|
+
if path.is_dir():
|
116
|
+
print("is dir")
|
117
|
+
sys.exit(1)
|
118
|
+
|
104
119
|
if not path.exists():
|
105
120
|
ErrorPrinter.print_hint("Source file does not exist")
|
106
121
|
sys.exit(1)
|
@@ -111,11 +126,11 @@ def __copy_to_remote(source: str, dest: str, project: str) -> None:
|
|
111
126
|
res = Rest.handle_post(f"/api/project/{project}/files/storage{rcs_path}", return_response=True)
|
112
127
|
if res is None:
|
113
128
|
return
|
114
|
-
|
115
|
-
url =
|
116
|
-
|
129
|
+
json_res = res.json()
|
130
|
+
url = json_res["url"]
|
131
|
+
headers = json_res["headers"]
|
117
132
|
try:
|
118
|
-
upload.upload_signed_url(url, source,
|
133
|
+
upload.upload_signed_url(url, source, headers)
|
119
134
|
except IsADirectoryError:
|
120
135
|
ErrorPrinter.print_hint(f"Supplied source file '{source}' is a directory but must be a file")
|
121
136
|
|
@@ -0,0 +1,30 @@
|
|
1
|
+
import json
|
2
|
+
import sys
|
3
|
+
|
4
|
+
import typer
|
5
|
+
|
6
|
+
from cli.cloud.rest_helper import RestHelper
|
7
|
+
|
8
|
+
app = typer.Typer()
|
9
|
+
|
10
|
+
|
11
|
+
@app.command(name="list", help="List your available organisations")
|
12
|
+
def list_orgs() -> None:
|
13
|
+
r = RestHelper.handle_get("/api/home", return_response=True)
|
14
|
+
if r is None:
|
15
|
+
return
|
16
|
+
if r.status_code == 200:
|
17
|
+
j = list(
|
18
|
+
map(
|
19
|
+
lambda x: {
|
20
|
+
"uid": x["billableUnitUser"]["billableUnit"]["uid"],
|
21
|
+
"displayName": x["billableUnitUser"]["billableUnit"]["displayName"],
|
22
|
+
},
|
23
|
+
r.json(),
|
24
|
+
)
|
25
|
+
)
|
26
|
+
print(json.dumps(j))
|
27
|
+
else:
|
28
|
+
print(f"Got status code: {r.status_code}")
|
29
|
+
print(r.text)
|
30
|
+
sys.exit(1)
|
cli/cloud/projects.py
CHANGED
@@ -25,8 +25,8 @@ def list_projects(organisation: str = typer.Option(..., help="Organisation ID",
|
|
25
25
|
|
26
26
|
@app.command(name="create")
|
27
27
|
def create_project(
|
28
|
+
project_uid: str = typer.Argument(help="Project UID"),
|
28
29
|
organisation: str = typer.Option(..., help="Organisation ID", envvar="REMOTIVE_CLOUD_ORGANISATION"),
|
29
|
-
project_uid: str = typer.Option(..., help="Project UID"),
|
30
30
|
project_display_name: str = typer.Option(default="", help="Project display name"),
|
31
31
|
) -> None:
|
32
32
|
create_project_req = {
|
@@ -39,5 +39,5 @@ def create_project(
|
|
39
39
|
|
40
40
|
|
41
41
|
@app.command(name="delete")
|
42
|
-
def delete(project: str = typer.
|
42
|
+
def delete(project: str = typer.Argument(help="Project ID", envvar="REMOTIVE_CLOUD_PROJECT")) -> None:
|
43
43
|
Rest.handle_delete(url=f"/api/project/{project}")
|
cli/cloud/recordings.py
CHANGED
@@ -309,23 +309,35 @@ def upload( # noqa: C901
|
|
309
309
|
err_console.print(f":boom: [bold red]Got status code[/bold red]: {upload_response.status_code} {upload_response.text}")
|
310
310
|
|
311
311
|
|
312
|
+
# TODO - Change to use Path for directory # pylint: disable=W0511
|
312
313
|
@app.command()
|
313
314
|
def upload_broker_configuration( # noqa: C901
|
314
|
-
directory:
|
315
|
+
directory: Path = typer.Argument(
|
316
|
+
...,
|
317
|
+
exists=True,
|
318
|
+
file_okay=False,
|
319
|
+
dir_okay=True,
|
320
|
+
writable=False,
|
321
|
+
readable=True,
|
322
|
+
resolve_path=True,
|
323
|
+
help="Directory to upload",
|
324
|
+
),
|
315
325
|
recording_session: str = typer.Option(..., help="Recording session id", envvar="REMOTIVE_CLOUD_RECORDING_SESSION"),
|
316
326
|
project: str = typer.Option(..., help="Project ID", envvar="REMOTIVE_CLOUD_PROJECT"),
|
317
327
|
overwrite: bool = typer.Option(False, help="Overwrite existing configuration if it exists"),
|
318
328
|
) -> None:
|
329
|
+
"""
|
330
|
+
Uploads a broker configuration directory
|
331
|
+
"""
|
319
332
|
# pylint: disable=R0914,R0915
|
333
|
+
|
320
334
|
# Must end with /
|
321
|
-
if not directory.endswith("/"):
|
322
|
-
directory = f"{directory}/"
|
323
335
|
|
324
336
|
#
|
325
337
|
# List files in specified directory. Look for interfaces.json and use that directory where this is located
|
326
338
|
# as configuration home directory
|
327
339
|
#
|
328
|
-
files = list(filter(lambda item: "interfaces.json" in item, glob.iglob(directory + "
|
340
|
+
files = list(filter(lambda item: "interfaces.json" in item, glob.iglob(str(directory) + "/**/**", recursive=True)))
|
329
341
|
if len(files) == 0:
|
330
342
|
sys.stderr.write("No interfaces.json found in directory, this file is required")
|
331
343
|
raise typer.Exit(1)
|
@@ -362,7 +374,7 @@ def upload_broker_configuration( # noqa: C901
|
|
362
374
|
file_infos = list(
|
363
375
|
map(
|
364
376
|
lambda item: {"local_path": item, "remote_path": f"/{broker_config_dir_name}{item.rsplit(broker_config_dir_name, 1)[-1]}"},
|
365
|
-
glob.iglob(directory + "
|
377
|
+
glob.iglob(str(directory) + "/**/*.*", recursive=True),
|
366
378
|
)
|
367
379
|
)
|
368
380
|
|
@@ -406,7 +418,7 @@ def upload_broker_configuration( # noqa: C901
|
|
406
418
|
|
407
419
|
|
408
420
|
@app.command(help="Downloads the specified broker configuration directory as zip file")
|
409
|
-
def
|
421
|
+
def download_broker_configuration(
|
410
422
|
broker_config_name: str = typer.Argument(..., help="Broker config name"),
|
411
423
|
recording_session: str = typer.Option(..., help="Recording session id", envvar="REMOTIVE_CLOUD_RECORDING_SESSION"),
|
412
424
|
project: str = typer.Option(..., help="Project ID", envvar="REMOTIVE_CLOUD_PROJECT"),
|
@@ -425,7 +437,7 @@ def download_configuration(
|
|
425
437
|
|
426
438
|
|
427
439
|
@app.command(help="Delete the specified broker configuration")
|
428
|
-
def
|
440
|
+
def delete_broker_configuration(
|
429
441
|
broker_config_name: str = typer.Argument(..., help="Broker config name"),
|
430
442
|
recording_session: str = typer.Option(..., help="Recording session id", envvar="REMOTIVE_CLOUD_RECORDING_SESSION"),
|
431
443
|
project: str = typer.Option(..., help="Project ID", envvar="REMOTIVE_CLOUD_PROJECT"),
|
@@ -436,11 +448,11 @@ def delete_configuration(
|
|
436
448
|
@app.command(help="Copy recording to another project")
|
437
449
|
def copy(
|
438
450
|
recording_session: str = typer.Argument(..., help="Recording session id"),
|
439
|
-
|
440
|
-
|
451
|
+
from_project: str = typer.Option(..., help="Source project"),
|
452
|
+
to_project: str = typer.Option(..., help="Destination project"),
|
441
453
|
) -> None:
|
442
454
|
Rest.handle_post(
|
443
|
-
url=f"/api/project/{
|
455
|
+
url=f"/api/project/{from_project}/files/recording/{recording_session}/copy", body=json.dumps({"projectUid": to_project})
|
444
456
|
)
|
445
457
|
|
446
458
|
|
cli/cloud/resumable_upload.py
CHANGED
@@ -1,5 +1,8 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
|
1
3
|
import os
|
2
4
|
import sys
|
5
|
+
from typing import Dict
|
3
6
|
|
4
7
|
import requests
|
5
8
|
from rich.progress import wrap_file
|
@@ -21,11 +24,12 @@ def __get_uploaded_bytes(upload_url: str) -> int:
|
|
21
24
|
return 0
|
22
25
|
|
23
26
|
|
24
|
-
def
|
27
|
+
def with_resumable_upload_signed_url(signed_url: str, source_file_name: str, content_type: str) -> None:
|
25
28
|
"""
|
26
29
|
Upload file to file storage with signed url and resumable upload.
|
27
30
|
Resumable upload will only work with the same URL and not if a new signed URL is requested with the
|
28
31
|
same object id.
|
32
|
+
:param content_type:
|
29
33
|
:param signed_url:
|
30
34
|
:param source_file_name:
|
31
35
|
:return:
|
@@ -60,3 +64,22 @@ def upload_signed_url(signed_url: str, source_file_name: str, content_type: str)
|
|
60
64
|
sys.exit(1)
|
61
65
|
|
62
66
|
print(f"File {source_file_name} uploaded successfully.")
|
67
|
+
|
68
|
+
|
69
|
+
def upload_signed_url(signed_url: str, source_file_name: str, headers: Dict[str, str]) -> None:
|
70
|
+
"""
|
71
|
+
Upload file to file storage with signed url and resumable upload.
|
72
|
+
Resumable upload will only work with the same URL and not if a new signed URL is requested with the
|
73
|
+
same object id.
|
74
|
+
:param headers:
|
75
|
+
:param signed_url:
|
76
|
+
:param source_file_name:
|
77
|
+
:return:
|
78
|
+
"""
|
79
|
+
with open(source_file_name, "rb") as f:
|
80
|
+
response = requests.put(signed_url, headers=headers, timeout=60, data=f)
|
81
|
+
if response.status_code not in (200, 201, 308):
|
82
|
+
ErrorPrinter.print_generic_error(f"Failed to upload file: {response.status_code} - {response.text}")
|
83
|
+
sys.exit(1)
|
84
|
+
|
85
|
+
print(f"File {source_file_name} uploaded successfully.")
|
@@ -4,25 +4,26 @@ cli/broker/brokers.py,sha256=oUadEL6xQ4bhXucBH-ZjL67VuERf19kn1g240v_lEpg,3197
|
|
4
4
|
cli/broker/export.py,sha256=LBWEu1hS9z4fPuu847numbCJe9ebaXjfHqqhplII4vg,4429
|
5
5
|
cli/broker/files.py,sha256=_MVwitQ5Z9-lNDb3biXqnlkKti8rizTEw0nnAViussU,4181
|
6
6
|
cli/broker/lib/__about__.py,sha256=xnZ5V6ZcHW9dhWLWdMzVjYJbEnMKpeXm0_S_mbNzypE,141
|
7
|
-
cli/broker/lib/broker.py,sha256=
|
7
|
+
cli/broker/lib/broker.py,sha256=7-MA3VJlWwfTGz8R9VYwQ2wmdwCczroDcIqa7rzkpGc,23988
|
8
8
|
cli/broker/license_flows.py,sha256=qJplaeugkUiypFGPdEIl5Asqlf7W3geJ-wU-QbYMP_8,7216
|
9
9
|
cli/broker/licenses.py,sha256=Ddl243re8RoeP9CoWWbIzwDePQ9l8r7ixmbd1gqn8f0,3973
|
10
10
|
cli/broker/playback.py,sha256=hdDKXGPuIE3gcT-kgQltgn5jsPzK19Yh9hiNcgtkLX0,3992
|
11
11
|
cli/broker/record.py,sha256=Oa6hUpS0Dgnt0f6Ig33vl0Jy8wN7wMXfemaxXWjRVoQ,1414
|
12
12
|
cli/broker/scripting.py,sha256=8577_C6siOk90s4G1ItIfAoFIUAkS0ItUl5kqR0cD-k,3792
|
13
|
-
cli/broker/signals.py,sha256=
|
13
|
+
cli/broker/signals.py,sha256=G54RrCUP9vonLouWL7IG0j7YqszVyM5jPr1WKHGZK34,7073
|
14
14
|
cli/cloud/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
15
15
|
cli/cloud/auth.py,sha256=CgIg_y7oBbRmOHtWEsmUrNrbBDf-Req0R7i_laKt_z8,3907
|
16
|
-
cli/cloud/auth_tokens.py,sha256=
|
16
|
+
cli/cloud/auth_tokens.py,sha256=usNWUqsRW2whs7EV2_aTHPqViuUHIwnWYekd4erDrVo,4788
|
17
17
|
cli/cloud/brokers.py,sha256=56MX74axZUhULzXSPnDfiq5uB8bpS1DXWskxOF2_tcQ,3892
|
18
|
-
cli/cloud/cloud_cli.py,sha256=
|
19
|
-
cli/cloud/configs.py,sha256=
|
20
|
-
cli/cloud/filestorage.py,sha256=
|
21
|
-
cli/cloud/
|
22
|
-
cli/cloud/
|
18
|
+
cli/cloud/cloud_cli.py,sha256=09YCHs8IivYsVJOsxlM5OMEqBdq3QUXtDsktcO8Kjyw,1263
|
19
|
+
cli/cloud/configs.py,sha256=xg3J-kaS-Pp0p9otV2cWl_oOWJzs_jZhXwFHz0gQxvc,4625
|
20
|
+
cli/cloud/filestorage.py,sha256=cCPDYwCyJxP4V_qK1_Gnsg_T-zVsw6QaZdY_l4s4vC0,5445
|
21
|
+
cli/cloud/organisations.py,sha256=txKQmSQEpTmeqlqngai8pwgQQEvRgeDd0dT_VzZ7RNc,752
|
22
|
+
cli/cloud/projects.py,sha256=YrwPJClC2Sq_y1HjPd_tzaiv4GEnnsXSXHBhtQCPdK0,1431
|
23
|
+
cli/cloud/recordings.py,sha256=jnsc39CmIQQ3DUu5Mpe7wrr6aLCK870TRi6TcgGmiY0,24137
|
23
24
|
cli/cloud/recordings_playback.py,sha256=PRzftmvG2iePrL9f6qTEXVOnyJ-etcyzn5w9CCxcSto,11539
|
24
25
|
cli/cloud/rest_helper.py,sha256=Sky-Lc0YaKbSUdSy3O5AK2FffKAVjAeVMrZLHiUILyU,11294
|
25
|
-
cli/cloud/resumable_upload.py,sha256=
|
26
|
+
cli/cloud/resumable_upload.py,sha256=sYThyhseXRniOMbctbO5p4BGVb9b7BXVBcmcZXwnClM,3550
|
26
27
|
cli/cloud/sample_recordings.py,sha256=OVX32U1dkkkJZysbgr5Dy515oOQKnwBAbZYzV_QUu1g,690
|
27
28
|
cli/cloud/service_account_tokens.py,sha256=bchcyK0tRo-mTF312tZsvlHgNB2Azza_snbT2di1Oqg,2413
|
28
29
|
cli/cloud/service_accounts.py,sha256=XOIPobUamCLIaufjyvb33XJDwy6uRqW5ZljZx3GYEfo,1659
|
@@ -37,8 +38,8 @@ cli/tools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
37
38
|
cli/tools/can/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
38
39
|
cli/tools/can/can.py,sha256=8uATViSFlpkdSiIm4fzbuQi1_m7V9Pym-K17TaJQRHU,2262
|
39
40
|
cli/tools/tools.py,sha256=0KU-hXR1f9xHP4BOG9A9eXfmICLmNuQCOU8ueF6iGg0,198
|
40
|
-
remotivelabs_cli-0.0.
|
41
|
-
remotivelabs_cli-0.0.
|
42
|
-
remotivelabs_cli-0.0.
|
43
|
-
remotivelabs_cli-0.0.
|
44
|
-
remotivelabs_cli-0.0.
|
41
|
+
remotivelabs_cli-0.0.28.dist-info/LICENSE,sha256=qDPP_yfuv1fF-u7EfexN-cN3M8aFgGVndGhGLovLKz0,608
|
42
|
+
remotivelabs_cli-0.0.28.dist-info/METADATA,sha256=OrX8uX05_oDur8eFNmFBScQR-EJCh8ao72faNclpLAE,1318
|
43
|
+
remotivelabs_cli-0.0.28.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
44
|
+
remotivelabs_cli-0.0.28.dist-info/entry_points.txt,sha256=lvDhPgagLqW_KTnLPCwKSqfYlEp-1uYVosRiPjsVj10,45
|
45
|
+
remotivelabs_cli-0.0.28.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|