remotivelabs-cli 0.0.29__py3-none-any.whl → 0.0.31__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/cloud/filestorage.py +7 -7
- cli/cloud/recordings.py +42 -6
- cli/cloud/rest_helper.py +4 -4
- cli/cloud/resumable_upload.py +7 -5
- {remotivelabs_cli-0.0.29.dist-info → remotivelabs_cli-0.0.31.dist-info}/METADATA +1 -1
- {remotivelabs_cli-0.0.29.dist-info → remotivelabs_cli-0.0.31.dist-info}/RECORD +9 -9
- {remotivelabs_cli-0.0.29.dist-info → remotivelabs_cli-0.0.31.dist-info}/LICENSE +0 -0
- {remotivelabs_cli-0.0.29.dist-info → remotivelabs_cli-0.0.31.dist-info}/WHEEL +0 -0
- {remotivelabs_cli-0.0.29.dist-info → remotivelabs_cli-0.0.31.dist-info}/entry_points.txt +0 -0
cli/cloud/filestorage.py
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
from __future__ import annotations
|
2
2
|
|
3
|
+
import json
|
3
4
|
import os.path
|
4
5
|
import sys
|
5
6
|
from pathlib import Path
|
@@ -75,6 +76,7 @@ def delete_file(
|
|
75
76
|
def copy_file( # noqa: C901 # type: ignore[too-many-branches] # pylint: disable=no-member
|
76
77
|
source: str = typer.Argument(default=..., help="Remote or local path to source file"),
|
77
78
|
dest: str = typer.Argument(default=..., help="Remote or local path to destination file"),
|
79
|
+
overwrite: bool = typer.Option(default=False, help="Overwrite existing file on RCS"),
|
78
80
|
project: str = typer.Option(..., help="Project ID", envvar="REMOTIVE_CLOUD_PROJECT"),
|
79
81
|
) -> None:
|
80
82
|
"""
|
@@ -100,20 +102,17 @@ def copy_file( # noqa: C901 # type: ignore[too-many-branches] # pylint: disabl
|
|
100
102
|
else:
|
101
103
|
path = Path(source)
|
102
104
|
if path.is_dir():
|
103
|
-
print("is dir")
|
104
105
|
for file_path in path.rglob("*"):
|
105
106
|
if file_path.is_file():
|
106
|
-
|
107
|
-
__copy_to_remote(source=source, dest=dest, project=project)
|
107
|
+
__copy_to_remote(source=source, dest=dest, project=project, overwrite=overwrite)
|
108
108
|
sys.exit(1)
|
109
109
|
else:
|
110
|
-
__copy_to_remote(source=source, dest=dest, project=project)
|
110
|
+
__copy_to_remote(source=source, dest=dest, project=project, overwrite=overwrite)
|
111
111
|
|
112
112
|
|
113
|
-
def __copy_to_remote(source: str, dest: str, project: str) -> None:
|
113
|
+
def __copy_to_remote(source: str, dest: str, project: str, overwrite: bool) -> None:
|
114
114
|
path = Path(source)
|
115
115
|
if path.is_dir():
|
116
|
-
print("is dir")
|
117
116
|
sys.exit(1)
|
118
117
|
|
119
118
|
if not path.exists():
|
@@ -123,7 +122,8 @@ def __copy_to_remote(source: str, dest: str, project: str) -> None:
|
|
123
122
|
rcs_path = __check_rcs_path(dest)
|
124
123
|
if rcs_path.endswith("/"):
|
125
124
|
rcs_path = rcs_path + filename
|
126
|
-
|
125
|
+
upload_options = {"overwrite": "always" if overwrite else "never"}
|
126
|
+
res = Rest.handle_post(f"/api/project/{project}/files/storage{rcs_path}", return_response=True, body=json.dumps(upload_options))
|
127
127
|
if res is None:
|
128
128
|
return
|
129
129
|
json_res = res.json()
|
cli/cloud/recordings.py
CHANGED
@@ -58,7 +58,9 @@ def list_recordings(
|
|
58
58
|
"""
|
59
59
|
|
60
60
|
if is_processing:
|
61
|
-
Rest.handle_get(f"/api/project/{project}/files/recording/processing")
|
61
|
+
res = Rest.handle_get(f"/api/project/{project}/files/recording/processing", return_response=True)
|
62
|
+
json_res: List[Dict[str, Any]] = res.json()
|
63
|
+
print(json.dumps(list(filter(lambda r: r["status"] == "RUNNING" or r["status"] == "FAILED", json_res))))
|
62
64
|
else:
|
63
65
|
Rest.handle_get(f"/api/project/{project}/files/recording")
|
64
66
|
|
@@ -79,7 +81,44 @@ def describe(
|
|
79
81
|
# body=json.dumps({'projectUid': target_project}))
|
80
82
|
|
81
83
|
|
82
|
-
|
84
|
+
@app.command(name="import")
|
85
|
+
def import_as_recording(
|
86
|
+
project: str = typer.Option(..., help="Project ID", envvar="REMOTIVE_CLOUD_PROJECT"),
|
87
|
+
path: str = typer.Argument(default=..., help="Remote storage path to file to delete"),
|
88
|
+
) -> None:
|
89
|
+
"""
|
90
|
+
Imports a file from Storage as a recording.
|
91
|
+
NOTE that Storage is not yet available to all customers
|
92
|
+
"""
|
93
|
+
|
94
|
+
if path.startswith("rcs://"):
|
95
|
+
final_path = __check_rcs_path(path)
|
96
|
+
else:
|
97
|
+
ErrorPrinter.print_hint("Path must start with rcs://")
|
98
|
+
sys.exit(1)
|
99
|
+
|
100
|
+
Rest.handle_post(
|
101
|
+
url=f"/api/project/{project}/files/recording",
|
102
|
+
return_response=True,
|
103
|
+
progress_label=f"Importing {final_path}...",
|
104
|
+
body=json.dumps({"path": final_path}),
|
105
|
+
)
|
106
|
+
|
107
|
+
ErrorPrinter.print_hint(
|
108
|
+
f"Import started, you can track progress with 'remotive cloud recordings list --is-processing --project {project}'"
|
109
|
+
)
|
110
|
+
|
111
|
+
|
112
|
+
# Copied from filestorage
|
113
|
+
def __check_rcs_path(path: str) -> str:
|
114
|
+
rcs_path = path.replace("rcs://", "/")
|
115
|
+
if rcs_path.startswith("/."):
|
116
|
+
ErrorPrinter.print_hint("Invalid path")
|
117
|
+
sys.exit(1)
|
118
|
+
return rcs_path
|
119
|
+
|
120
|
+
|
121
|
+
def do_start(name: str, project: str, api_key: str, return_response: bool = False) -> requests.Response:
|
83
122
|
if api_key == "":
|
84
123
|
body = {"size": "S"}
|
85
124
|
else:
|
@@ -125,13 +164,10 @@ def mount( # noqa: C901
|
|
125
164
|
else:
|
126
165
|
r = Rest.handle_get(url=f"/api/project/{project}/brokers/{broker}", return_response=True, allow_status_codes=[404])
|
127
166
|
|
128
|
-
if r is None:
|
129
|
-
sys.exit(1)
|
130
167
|
if r.status_code == 404:
|
131
168
|
if ensure_broker_started:
|
132
169
|
r = do_start(broker, project, "", return_response=True)
|
133
|
-
|
134
|
-
sys.exit(1)
|
170
|
+
|
135
171
|
if r.status_code != 200:
|
136
172
|
print(r.text)
|
137
173
|
sys.exit(1)
|
cli/cloud/rest_helper.py
CHANGED
@@ -102,7 +102,7 @@ class RestHelper:
|
|
102
102
|
progress_label: str = "Fetching...",
|
103
103
|
use_progress_indicator: bool = True,
|
104
104
|
timeout: int = 20,
|
105
|
-
) -> requests.Response
|
105
|
+
) -> requests.Response:
|
106
106
|
# pylint: disable=R0913
|
107
107
|
# Returns a Response object if succesfull otherwise None
|
108
108
|
if params is None:
|
@@ -118,7 +118,7 @@ class RestHelper:
|
|
118
118
|
RestHelper.check_api_result(r, allow_status_codes)
|
119
119
|
return r
|
120
120
|
RestHelper.print_api_result(r)
|
121
|
-
|
121
|
+
sys.exit(0)
|
122
122
|
|
123
123
|
@staticmethod
|
124
124
|
def has_access(url: str, params: Any = {}) -> bool: # pylint: disable=W0102
|
@@ -174,7 +174,7 @@ class RestHelper:
|
|
174
174
|
@staticmethod
|
175
175
|
def handle_post( # pylint: disable=W0102
|
176
176
|
url: str, body: Any = None, params: Any = {}, progress_label: str = "Processing...", return_response: bool = False
|
177
|
-
) -> requests.Response
|
177
|
+
) -> requests.Response:
|
178
178
|
# Returns a Response object if succesfull otherwise, None
|
179
179
|
RestHelper.ensure_auth_token()
|
180
180
|
RestHelper.__headers["content-type"] = "application/json"
|
@@ -187,7 +187,7 @@ class RestHelper:
|
|
187
187
|
return r
|
188
188
|
|
189
189
|
RestHelper.print_api_result(r)
|
190
|
-
|
190
|
+
sys.exit(0)
|
191
191
|
|
192
192
|
@staticmethod
|
193
193
|
def handle_put(url: str, body: Any = None, params: Any = {}, return_response: bool = False) -> requests.Response | None: # pylint: disable=W0102
|
cli/cloud/resumable_upload.py
CHANGED
@@ -76,10 +76,12 @@ def upload_signed_url(signed_url: str, source_file_name: str, headers: Dict[str,
|
|
76
76
|
:param source_file_name:
|
77
77
|
:return:
|
78
78
|
"""
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
79
|
+
|
80
|
+
with open(source_file_name, "rb") as file:
|
81
|
+
with wrap_file(file, os.stat(source_file_name).st_size, description=f"Uploading {source_file_name}...") as f:
|
82
|
+
response = requests.put(signed_url, headers=headers, timeout=60, data=f)
|
83
|
+
if response.status_code not in (200, 201, 308):
|
84
|
+
ErrorPrinter.print_generic_error(f"Failed to upload file: {response.status_code} - {response.text}")
|
85
|
+
sys.exit(1)
|
84
86
|
|
85
87
|
print(f"File {source_file_name} uploaded successfully.")
|
@@ -16,13 +16,13 @@ cli/cloud/auth_tokens.py,sha256=0U60Gk2-TnAUff5anZmTB1rOEninNvYy1o5ihCqgj8A,4525
|
|
16
16
|
cli/cloud/brokers.py,sha256=DNj79MTkPylKUQbr-iPUhQgfNJLAW8UehnvgpEmNH_k,3890
|
17
17
|
cli/cloud/cloud_cli.py,sha256=09YCHs8IivYsVJOsxlM5OMEqBdq3QUXtDsktcO8Kjyw,1263
|
18
18
|
cli/cloud/configs.py,sha256=xg3J-kaS-Pp0p9otV2cWl_oOWJzs_jZhXwFHz0gQxvc,4625
|
19
|
-
cli/cloud/filestorage.py,sha256=
|
19
|
+
cli/cloud/filestorage.py,sha256=BZbSk9abuLYw9TjGsQpfYMobtE4VLgXFrWD1sVvGolY,5621
|
20
20
|
cli/cloud/organisations.py,sha256=txKQmSQEpTmeqlqngai8pwgQQEvRgeDd0dT_VzZ7RNc,752
|
21
21
|
cli/cloud/projects.py,sha256=YrwPJClC2Sq_y1HjPd_tzaiv4GEnnsXSXHBhtQCPdK0,1431
|
22
|
-
cli/cloud/recordings.py,sha256=
|
22
|
+
cli/cloud/recordings.py,sha256=jai5Gim28UmZFGniUI9qKDwtLoi2Nllv4eyPeIk3OAc,25366
|
23
23
|
cli/cloud/recordings_playback.py,sha256=PRzftmvG2iePrL9f6qTEXVOnyJ-etcyzn5w9CCxcSto,11539
|
24
|
-
cli/cloud/rest_helper.py,sha256=
|
25
|
-
cli/cloud/resumable_upload.py,sha256=
|
24
|
+
cli/cloud/rest_helper.py,sha256=lZp0NjQ8yOaggQGNiqNxHex_YFOmuq0rnLPtpLq3Z3Q,11470
|
25
|
+
cli/cloud/resumable_upload.py,sha256=5R6TLq9j8h-qs5bgGFC-lVaEsTI4DoAiTsZcROVtqgw,3688
|
26
26
|
cli/cloud/sample_recordings.py,sha256=OVX32U1dkkkJZysbgr5Dy515oOQKnwBAbZYzV_QUu1g,690
|
27
27
|
cli/cloud/service_account_tokens.py,sha256=263u1bRmBKfYsxL6TV6YjReUBUaVHWc3ETCd7AS3DTU,2297
|
28
28
|
cli/cloud/service_accounts.py,sha256=XOIPobUamCLIaufjyvb33XJDwy6uRqW5ZljZx3GYEfo,1659
|
@@ -36,8 +36,8 @@ cli/tools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
36
36
|
cli/tools/can/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
37
37
|
cli/tools/can/can.py,sha256=8uATViSFlpkdSiIm4fzbuQi1_m7V9Pym-K17TaJQRHU,2262
|
38
38
|
cli/tools/tools.py,sha256=0KU-hXR1f9xHP4BOG9A9eXfmICLmNuQCOU8ueF6iGg0,198
|
39
|
-
remotivelabs_cli-0.0.
|
40
|
-
remotivelabs_cli-0.0.
|
41
|
-
remotivelabs_cli-0.0.
|
42
|
-
remotivelabs_cli-0.0.
|
43
|
-
remotivelabs_cli-0.0.
|
39
|
+
remotivelabs_cli-0.0.31.dist-info/LICENSE,sha256=qDPP_yfuv1fF-u7EfexN-cN3M8aFgGVndGhGLovLKz0,608
|
40
|
+
remotivelabs_cli-0.0.31.dist-info/METADATA,sha256=hXSuC1H53XacGz8LX3D4ySgdUIOncQG7iIWQEm5NdkI,1318
|
41
|
+
remotivelabs_cli-0.0.31.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
42
|
+
remotivelabs_cli-0.0.31.dist-info/entry_points.txt,sha256=lvDhPgagLqW_KTnLPCwKSqfYlEp-1uYVosRiPjsVj10,45
|
43
|
+
remotivelabs_cli-0.0.31.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|