remotivelabs-cli 0.0.21__py3-none-any.whl → 0.0.23__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/recordings.py CHANGED
@@ -6,7 +6,10 @@ import os
6
6
  import re
7
7
  import sys
8
8
  import tempfile
9
+ import time
10
+ import urllib.parse
9
11
  from pathlib import Path
12
+ from typing import Dict, List, Union
10
13
 
11
14
  import grpc
12
15
  import requests
@@ -193,7 +196,7 @@ def delete_recording_file(
193
196
 
194
197
 
195
198
  @app.command()
196
- def upload(
199
+ def upload( # noqa: C901
197
200
  path: Path = typer.Argument(
198
201
  ...,
199
202
  exists=True,
@@ -205,38 +208,86 @@ def upload(
205
208
  help="Path to recording file to upload",
206
209
  ),
207
210
  project: str = typer.Option(..., help="Project ID", envvar="REMOTIVE_CLOUD_PROJECT"),
208
- recording_type: str = typer.Option("remotive-broker", help="Type of recording"),
209
- signal_database: str = typer.Option(None, help="Signal database to use with candump"),
211
+ recording_session: str = typer.Option(default=None, help="Optional existing recording to upload file to"),
210
212
  ):
211
- # TODO - Test to do this with typer Enums instead
212
- # Validate this here to validate before we start any progress
213
- if recording_type == "candump" and (signal_database is None or signal_database == ""):
214
- ErrorPrinter.print_hint("Option --signal-database is required with --recording-type is 'candump'")
215
- exit(1)
213
+ """
214
+ Uploads a recording to RemotiveCloud.
215
+ Except for recordings from RemotiveBroker you can also upload Can ASC (.asc), Can BLF(.blf) and Can LOG (.log, .txt)
216
+ """
216
217
 
217
218
  filename = os.path.basename(path.name)
218
219
  rest.ensure_auth_token()
219
220
 
220
- if recording_type == "candump":
221
- rest.headers["x-recording-type"] = "candump"
222
- r = rest.handle_post(
223
- url=f"/api/project/{project}/files/recording/{filename}",
224
- return_response=True,
225
- progress_label="Requesting recording upload...",
226
- body=json.dumps({"dbcFile": signal_database}),
227
- )
228
- else:
221
+ if recording_session is None:
229
222
  r = rest.handle_post(f"/api/project/{project}/files/recording/{filename}", return_response=True)
223
+ else:
224
+ r = rest.handle_post(f"/api/project/{project}/files/recording/{recording_session}/recording-file/{filename}", return_response=True)
225
+
226
+ upload_url = r.text
227
+ url_path = urllib.parse.urlparse(upload_url).path
228
+ # Upload_id is the first part of the path
229
+ match = re.match(r"^/([^/]+)/organisation/(.*)$", url_path)
230
+ if match:
231
+ upload_id = match.group(1)
232
+ else:
233
+ ErrorPrinter.print_generic_error(
234
+ "Something went wrong, please try again. Please contact RemotiveLabs support if this problem remains"
235
+ )
236
+ ErrorPrinter.print_hint("Please make sure to use the latest version of RemotiveCLI")
237
+ exit(1)
230
238
 
231
- response = rest.upload_file_with_signed_url(path=path, url=r.text, upload_headers={"Content-Type": "application/x-www-form-urlencoded"})
239
+ upload_response = rest.upload_file_with_signed_url(
240
+ path=path, url=upload_url, upload_headers={"Content-Type": "application/x-www-form-urlencoded"}, return_response=True
241
+ )
242
+
243
+ # Exact same as in cloud console
244
+ def get_processing_message(step: str) -> str:
245
+ if step == "REQUESTED":
246
+ return "Preparing file..."
247
+ if step == "VALIDATING":
248
+ return "Validating file..."
249
+ if step == "CONVERT":
250
+ return "Converting file..."
251
+ if step == "SPLIT":
252
+ return "Splitting file..."
253
+ if step == "ZIP":
254
+ return "Compressing file..."
255
+ if step == "FINALIZE":
256
+ return "Finishing up..."
257
+ return "Processing..."
258
+
259
+ # print(response)
260
+ if 200 <= upload_response.status_code < 300:
261
+ # We need to print the error message outside the with Progress so the indicator is closed
262
+ error_message: Union[str, None] = None
263
+ with Progress(SpinnerColumn(), TextColumn("[progress.description]{task.description}"), transient=True) as p:
264
+ t = p.add_task("Processing...", total=1)
265
+ while True:
266
+ time.sleep(1)
267
+ r = rest.handle_get(
268
+ f"/api/project/{project}/files/recording/processing", return_response=True, use_progress_indicator=False
269
+ )
270
+ status_list: List[Dict[str, any]] = r.json()
271
+ res = list(filter(lambda s: s["uploadId"] == upload_id, status_list))
272
+ if len(res) == 1:
273
+ tracking_state = res[0]
274
+ if tracking_state["status"] != "FAILED" and tracking_state["status"] != "SUCCESS":
275
+ p.update(task_id=t, description=get_processing_message(tracking_state["step"]))
276
+ else:
277
+ if tracking_state["status"] == "FAILED":
278
+ error_message = f"Processing of uploaded file failed: {tracking_state['errors'][0]['message']}"
279
+ else:
280
+ print("File successfully uploaded")
281
+ break
282
+ else:
283
+ error_message = "Something went wrong, please try again. Please contact RemotiveLabs support if this problem remains"
284
+ break
285
+ if error_message is not None:
286
+ ErrorPrinter.print_generic_error(error_message)
287
+ exit(1)
232
288
 
233
- if 200 <= response.status_code < 300:
234
- print(
235
- "File successfully uploaded, please run 'remotive cloud recordings list' "
236
- "to verify that the recording was successfully processed"
237
- )
238
289
  else:
239
- rest.err_console.print(f":boom: [bold red]Got status code[/bold red]: {response.status_code} {response.text}")
290
+ rest.err_console.print(f":boom: [bold red]Got status code[/bold red]: {upload_response.status_code} {upload_response.text}")
240
291
 
241
292
 
242
293
  @app.command()
@@ -450,9 +501,9 @@ def _do_change_playback_mode(mode: str, recording_session: str, broker: str, pro
450
501
  # Here we try to verify that we are operating on a recording that is mounted on the
451
502
  # broker so we can verify this before we try playback and can also present some good
452
503
  # error messages
453
- tmp = tempfile.NamedTemporaryFile()
454
- broker.download(".cloud.context", tmp.name, True)
455
- with open(tmp.name, "r") as f:
504
+ tmp = os.path.join(tempfile.gettempdir(), os.urandom(24).hex())
505
+ broker.download(".cloud.context", tmp, True)
506
+ with open(tmp, "r") as f:
456
507
  json_context = json.loads(f.read())
457
508
  if json_context["recordingSessionId"] != recording_session:
458
509
  ErrorPrinter.print_generic_error(
@@ -496,3 +547,9 @@ def get_filename_from_cd(cd):
496
547
  if len(fname) == 0:
497
548
  return None
498
549
  return fname[0]
550
+
551
+
552
+ def use_progress(label: str):
553
+ p = Progress(SpinnerColumn(), TextColumn("[progress.description]{task.description}"), transient=True)
554
+ t = p.add_task(label, total=1)
555
+ return (p, t)
cli/cloud/rest_helper.py CHANGED
@@ -185,7 +185,7 @@ def upload_file_with_signed_url(
185
185
  path: Union[str, Path], url: str, upload_headers: dict[str, str], return_response: bool = False, progress_label="Uploading..."
186
186
  ):
187
187
  with open(path, "rb") as file:
188
- with wrap_file(file, os.stat(path).st_size, description=progress_label) as f:
188
+ with wrap_file(file, os.stat(path).st_size, description=progress_label, transient=True) as f:
189
189
  r = requests.put(url, data=f, headers=upload_headers)
190
190
  if return_response:
191
191
  check_api_result(r)
cli/connect/connect.py CHANGED
@@ -1,5 +1,6 @@
1
1
  from __future__ import annotations
2
2
 
3
+ import json
3
4
  import sys
4
5
  from pathlib import Path
5
6
 
@@ -94,7 +95,14 @@ def protopie(
94
95
  if len(signal) > 0:
95
96
  signals_to_subscribe_to = list(map(to_subscribable_signal, signal))
96
97
  else:
97
- signals_to_subscribe_to = None
98
+ with open(config, "r") as f:
99
+ c = json.load(f)
100
+ s = c["subscription"]
101
+ ss = []
102
+ for entry in s.keys():
103
+ ss.append(SubscribableSignal(namespace=s[entry]["namespace"], name=entry))
104
+ print(ss)
105
+ signals_to_subscribe_to = ss
98
106
 
99
107
  protopie.do_connect(
100
108
  address=pp_connect_host,
@@ -3,6 +3,7 @@ from __future__ import annotations
3
3
  import json
4
4
  import os
5
5
  import time
6
+ import traceback
6
7
  from pathlib import Path
7
8
  from typing import Dict, List, Union
8
9
 
@@ -96,6 +97,8 @@ def _connect_to_broker(
96
97
  signal_name = get_signal_name(expression, s.name())
97
98
  io.emit("ppMessage", {"messageId": signal_name, "value": str(s.value())})
98
99
 
100
+ print(signals_to_subscribe_to)
101
+
99
102
  grpc_connect(on_signals, signals_to_subscribe_to)
100
103
 
101
104
 
@@ -107,6 +110,7 @@ def grpc_connect(on_signals, signals_to_subscribe_to: Union[List[SignalIdentifie
107
110
  client.connect(url=broker, api_key=x_api_key)
108
111
  client.on_signals = on_signals
109
112
 
113
+ print(signals_to_subscribe_to)
110
114
  subscription = client.subscribe(signals_to_subscribe_to=signals_to_subscribe_to, changed_values_only=False)
111
115
  pretty_print("Subscription to broker completed")
112
116
  pretty_print("Waiting for signals...")
@@ -132,6 +136,7 @@ def grpc_connect(on_signals, signals_to_subscribe_to: Union[List[SignalIdentifie
132
136
  subscription.cancel()
133
137
 
134
138
  except Exception as e:
139
+ print(traceback.format_exc())
135
140
  err_console.print(f":boom: {e}")
136
141
  # exit(1)
137
142
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: remotivelabs-cli
3
- Version: 0.0.21
3
+ Version: 0.0.23
4
4
  Summary: CLI for operating RemotiveCloud and RemotiveBroker
5
5
  Author: Johan Rask
6
6
  Author-email: johan.rask@remotivelabs.com
@@ -18,15 +18,15 @@ cli/cloud/brokers.py,sha256=wa3uMg91IZdrP0tMpTdO9cBIkZHtMHxQ-zEXwFiye_I,4127
18
18
  cli/cloud/cloud_cli.py,sha256=nRRXFF_IgUMayerxS-h7oqsNe6tt34Q5VeThq8gatEg,1443
19
19
  cli/cloud/configs.py,sha256=2p1mCHf5BwYNtwbY0Cbed5t6-79WHGKWU4Fv6LuJ21o,4069
20
20
  cli/cloud/projects.py,sha256=-uqltAOficwprOKaPd2R0Itm4sqTz3VJNs9Sc8jtO5k,1369
21
- cli/cloud/recordings.py,sha256=aBQeZW569cBcf_qLZA5StmgNnnSKYaaunn91SXnJVQM,20801
21
+ cli/cloud/recordings.py,sha256=QpNb9HWK_LC7Trex8E7RevEy7GTOBZHw0RsgOt_RmUA,23286
22
22
  cli/cloud/recordings_playback.py,sha256=crrwQ3kl8LzCVBan9B1a15t-vhDCNYqLKSVQbLf58Ng,10907
23
- cli/cloud/rest_helper.py,sha256=WK5We-vWg0GwnTq37OyKVuQTc58RFkPuA0kq5wjDtCk,7769
23
+ cli/cloud/rest_helper.py,sha256=dUVmykp0_M4pxzI3WiGoURjlaeCe_V_2h7JwnteW69w,7785
24
24
  cli/cloud/sample_recordings.py,sha256=g1X6JTxvzWInSP9R1BJsDmL4WqvpEKqjdJR_xT4bo1U,639
25
25
  cli/cloud/service_account_tokens.py,sha256=7vjoMd6Xq7orWCUP7TVUVa86JA0OiX8O10NZcHUE6rM,2294
26
26
  cli/cloud/service_accounts.py,sha256=GCYdYPnP5uWVsg1bTIS67CmoPWDng5dupJHmlThrJ80,1606
27
27
  cli/connect/__init__.py,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
28
- cli/connect/connect.py,sha256=xeQLgbLvwB-l2pL6ulbOkYeMQZb5B_rLvy7oQVNa78k,3649
29
- cli/connect/protopie/protopie.py,sha256=8gRBwanAXL7hUYycpZUNV0JodM-jCRMMhC9G0LIZNzs,5720
28
+ cli/connect/connect.py,sha256=x4HH0yPUsBtLROOalB8J35U7UJq718cE0C57tCia2To,3927
29
+ cli/connect/protopie/protopie.py,sha256=sbzOG2130q2PlalhOD0CYU7oam-zdIJY9p6bGQsLsxY,5850
30
30
  cli/errors.py,sha256=sOjYasWbwqu2IcK4MvrG4ddpQ7idLGxiFYOxjhdsahM,1319
31
31
  cli/remotive.py,sha256=KKahzVZACa3MIBqt2lZDiSsDOTmoZIdNeKex8LJR8ZQ,1645
32
32
  cli/requirements.txt,sha256=Tjpv2HSAPemgKC-eJbwDw-gvAdklfJ18LixRcwzvQIU,78
@@ -35,8 +35,8 @@ cli/tools/__init__.py,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
35
35
  cli/tools/can/__init__.py,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
36
36
  cli/tools/can/can.py,sha256=kSd1c-nxxXyeKkm19oDILiDBZsKOcpjsUT0T3xox5Qs,2172
37
37
  cli/tools/tools.py,sha256=LwQdWMcJ19pCyKUsVfSB2B3R6ui61NxxFWP0Nrnd5Jk,198
38
- remotivelabs_cli-0.0.21.dist-info/LICENSE,sha256=qDPP_yfuv1fF-u7EfexN-cN3M8aFgGVndGhGLovLKz0,608
39
- remotivelabs_cli-0.0.21.dist-info/METADATA,sha256=hFU-4UmT2_YsKzVdIBwyWiT8ysdOjMqAt-_CbvrCQoU,1224
40
- remotivelabs_cli-0.0.21.dist-info/WHEEL,sha256=FMvqSimYX_P7y0a7UY-_Mc83r5zkBZsCYPm7Lr0Bsq4,88
41
- remotivelabs_cli-0.0.21.dist-info/entry_points.txt,sha256=lvDhPgagLqW_KTnLPCwKSqfYlEp-1uYVosRiPjsVj10,45
42
- remotivelabs_cli-0.0.21.dist-info/RECORD,,
38
+ remotivelabs_cli-0.0.23.dist-info/LICENSE,sha256=qDPP_yfuv1fF-u7EfexN-cN3M8aFgGVndGhGLovLKz0,608
39
+ remotivelabs_cli-0.0.23.dist-info/METADATA,sha256=nGPW6zDIEdqFujksCqmL3lKDNFgv5rF5hlEhexPmuZk,1224
40
+ remotivelabs_cli-0.0.23.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
41
+ remotivelabs_cli-0.0.23.dist-info/entry_points.txt,sha256=lvDhPgagLqW_KTnLPCwKSqfYlEp-1uYVosRiPjsVj10,45
42
+ remotivelabs_cli-0.0.23.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: poetry-core 1.8.1
2
+ Generator: poetry-core 1.9.0
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any