remotivelabs-cli 0.3.0__tar.gz → 0.3.2__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 remotivelabs-cli might be problematic. Click here for more details.

Files changed (76) hide show
  1. {remotivelabs_cli-0.3.0 → remotivelabs_cli-0.3.2}/PKG-INFO +1 -1
  2. remotivelabs_cli-0.3.2/cli/broker/__init__.py +36 -0
  3. remotivelabs_cli-0.3.2/cli/broker/discovery.py +43 -0
  4. {remotivelabs_cli-0.3.0 → remotivelabs_cli-0.3.2}/cli/broker/export.py +6 -36
  5. {remotivelabs_cli-0.3.0 → remotivelabs_cli-0.3.2}/cli/broker/files.py +12 -12
  6. {remotivelabs_cli-0.3.0 → remotivelabs_cli-0.3.2}/cli/broker/lib/broker.py +13 -18
  7. {remotivelabs_cli-0.3.0 → remotivelabs_cli-0.3.2}/cli/broker/lib/helper.py +6 -7
  8. {remotivelabs_cli-0.3.0 → remotivelabs_cli-0.3.2}/cli/broker/license_flows.py +11 -13
  9. {remotivelabs_cli-0.3.0 → remotivelabs_cli-0.3.2}/cli/broker/playback.py +10 -10
  10. {remotivelabs_cli-0.3.0 → remotivelabs_cli-0.3.2}/cli/broker/record.py +4 -4
  11. {remotivelabs_cli-0.3.0 → remotivelabs_cli-0.3.2}/cli/broker/scripting.py +6 -9
  12. {remotivelabs_cli-0.3.0 → remotivelabs_cli-0.3.2}/cli/broker/signals.py +17 -19
  13. {remotivelabs_cli-0.3.0 → remotivelabs_cli-0.3.2}/cli/cloud/auth/cmd.py +17 -14
  14. {remotivelabs_cli-0.3.0 → remotivelabs_cli-0.3.2}/cli/cloud/auth/login.py +16 -26
  15. {remotivelabs_cli-0.3.0 → remotivelabs_cli-0.3.2}/cli/cloud/auth_tokens.py +9 -13
  16. {remotivelabs_cli-0.3.0 → remotivelabs_cli-0.3.2}/cli/cloud/brokers.py +5 -9
  17. {remotivelabs_cli-0.3.0 → remotivelabs_cli-0.3.2}/cli/cloud/configs.py +4 -17
  18. {remotivelabs_cli-0.3.0 → remotivelabs_cli-0.3.2}/cli/cloud/organisations.py +8 -10
  19. {remotivelabs_cli-0.3.0 → remotivelabs_cli-0.3.2}/cli/cloud/projects.py +3 -3
  20. {remotivelabs_cli-0.3.0 → remotivelabs_cli-0.3.2}/cli/cloud/recordings.py +35 -61
  21. {remotivelabs_cli-0.3.0 → remotivelabs_cli-0.3.2}/cli/cloud/recordings_playback.py +22 -22
  22. {remotivelabs_cli-0.3.0 → remotivelabs_cli-0.3.2}/cli/cloud/resumable_upload.py +6 -6
  23. {remotivelabs_cli-0.3.0 → remotivelabs_cli-0.3.2}/cli/cloud/service_account_tokens.py +3 -2
  24. {remotivelabs_cli-0.3.0 → remotivelabs_cli-0.3.2}/cli/cloud/storage/cmd.py +2 -3
  25. {remotivelabs_cli-0.3.0 → remotivelabs_cli-0.3.2}/cli/cloud/storage/copy.py +2 -1
  26. {remotivelabs_cli-0.3.0 → remotivelabs_cli-0.3.2}/cli/connect/connect.py +4 -4
  27. {remotivelabs_cli-0.3.0 → remotivelabs_cli-0.3.2}/cli/connect/protopie/protopie.py +21 -29
  28. {remotivelabs_cli-0.3.0 → remotivelabs_cli-0.3.2}/cli/remotive.py +4 -7
  29. {remotivelabs_cli-0.3.0 → remotivelabs_cli-0.3.2}/cli/settings/core.py +4 -2
  30. {remotivelabs_cli-0.3.0 → remotivelabs_cli-0.3.2}/cli/settings/migration/migration_tools.py +2 -1
  31. {remotivelabs_cli-0.3.0 → remotivelabs_cli-0.3.2}/cli/tools/can/can.py +4 -7
  32. remotivelabs_cli-0.3.2/cli/topology/__init__.py +3 -0
  33. remotivelabs_cli-0.3.2/cli/topology/cmd.py +79 -0
  34. remotivelabs_cli-0.3.2/cli/topology/start_trial.py +105 -0
  35. {remotivelabs_cli-0.3.0 → remotivelabs_cli-0.3.2}/cli/typer/typer_utils.py +3 -6
  36. remotivelabs_cli-0.3.2/cli/utils/console.py +61 -0
  37. {remotivelabs_cli-0.3.0 → remotivelabs_cli-0.3.2}/cli/utils/rest_helper.py +23 -16
  38. {remotivelabs_cli-0.3.0 → remotivelabs_cli-0.3.2}/cli/utils/versions.py +2 -4
  39. {remotivelabs_cli-0.3.0 → remotivelabs_cli-0.3.2}/pyproject.toml +1 -1
  40. remotivelabs_cli-0.3.0/cli/broker/brokers.py +0 -93
  41. remotivelabs_cli-0.3.0/cli/errors.py +0 -44
  42. remotivelabs_cli-0.3.0/cli/topology/cmd.py +0 -101
  43. {remotivelabs_cli-0.3.0 → remotivelabs_cli-0.3.2}/LICENSE +0 -0
  44. {remotivelabs_cli-0.3.0 → remotivelabs_cli-0.3.2}/README.md +0 -0
  45. {remotivelabs_cli-0.3.0 → remotivelabs_cli-0.3.2}/cli/.DS_Store +0 -0
  46. {remotivelabs_cli-0.3.0 → remotivelabs_cli-0.3.2}/cli/__init__.py +0 -0
  47. {remotivelabs_cli-0.3.0 → remotivelabs_cli-0.3.2}/cli/api/cloud/tokens.py +0 -0
  48. {remotivelabs_cli-0.3.0 → remotivelabs_cli-0.3.2}/cli/broker/lib/__about__.py +0 -0
  49. {remotivelabs_cli-0.3.0 → remotivelabs_cli-0.3.2}/cli/broker/lib/client.py +0 -0
  50. {remotivelabs_cli-0.3.0 → remotivelabs_cli-0.3.2}/cli/broker/lib/signalcreator.py +0 -0
  51. {remotivelabs_cli-0.3.0 → remotivelabs_cli-0.3.2}/cli/broker/licenses.py +0 -0
  52. {remotivelabs_cli-0.3.0 → remotivelabs_cli-0.3.2}/cli/cloud/__init__.py +0 -0
  53. {remotivelabs_cli-0.3.0 → remotivelabs_cli-0.3.2}/cli/cloud/auth/__init__.py +0 -0
  54. {remotivelabs_cli-0.3.0 → remotivelabs_cli-0.3.2}/cli/cloud/licenses/__init__.py +0 -0
  55. {remotivelabs_cli-0.3.0 → remotivelabs_cli-0.3.2}/cli/cloud/licenses/cmd.py +0 -0
  56. {remotivelabs_cli-0.3.0 → remotivelabs_cli-0.3.2}/cli/cloud/sample_recordings.py +0 -0
  57. {remotivelabs_cli-0.3.0 → remotivelabs_cli-0.3.2}/cli/cloud/service_accounts.py +0 -0
  58. {remotivelabs_cli-0.3.0 → remotivelabs_cli-0.3.2}/cli/cloud/storage/__init__.py +0 -0
  59. {remotivelabs_cli-0.3.0 → remotivelabs_cli-0.3.2}/cli/cloud/storage/uri_or_path.py +0 -0
  60. {remotivelabs_cli-0.3.0 → remotivelabs_cli-0.3.2}/cli/cloud/uri.py +0 -0
  61. {remotivelabs_cli-0.3.0 → remotivelabs_cli-0.3.2}/cli/connect/__init__.py +0 -0
  62. {remotivelabs_cli-0.3.0 → remotivelabs_cli-0.3.2}/cli/settings/__init__.py +0 -0
  63. {remotivelabs_cli-0.3.0 → remotivelabs_cli-0.3.2}/cli/settings/config_file.py +0 -0
  64. {remotivelabs_cli-0.3.0 → remotivelabs_cli-0.3.2}/cli/settings/migration/__init__.py +0 -0
  65. {remotivelabs_cli-0.3.0 → remotivelabs_cli-0.3.2}/cli/settings/migration/migrate_all_token_files.py +0 -0
  66. {remotivelabs_cli-0.3.0 → remotivelabs_cli-0.3.2}/cli/settings/migration/migrate_config_file.py +0 -0
  67. {remotivelabs_cli-0.3.0 → remotivelabs_cli-0.3.2}/cli/settings/migration/migrate_legacy_dirs.py +0 -0
  68. {remotivelabs_cli-0.3.0 → remotivelabs_cli-0.3.2}/cli/settings/migration/migrate_token_file.py +0 -0
  69. {remotivelabs_cli-0.3.0 → remotivelabs_cli-0.3.2}/cli/settings/state_file.py +0 -0
  70. {remotivelabs_cli-0.3.0 → remotivelabs_cli-0.3.2}/cli/settings/token_file.py +0 -0
  71. {remotivelabs_cli-0.3.0 → remotivelabs_cli-0.3.2}/cli/tools/__init__.py +0 -0
  72. {remotivelabs_cli-0.3.0 → remotivelabs_cli-0.3.2}/cli/tools/can/__init__.py +0 -0
  73. {remotivelabs_cli-0.3.0 → remotivelabs_cli-0.3.2}/cli/tools/tools.py +0 -0
  74. {remotivelabs_cli-0.3.0 → remotivelabs_cli-0.3.2}/cli/typer/__init__.py +0 -0
  75. {remotivelabs_cli-0.3.0 → remotivelabs_cli-0.3.2}/cli/utils/__init__.py +0 -0
  76. {remotivelabs_cli-0.3.0 → remotivelabs_cli-0.3.2}/cli/utils/time.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: remotivelabs-cli
3
- Version: 0.3.0
3
+ Version: 0.3.2
4
4
  Summary: CLI for operating RemotiveCloud and RemotiveBroker
5
5
  Author: Johan Rask
6
6
  Author-email: johan.rask@remotivelabs.com
@@ -0,0 +1,36 @@
1
+ from __future__ import annotations
2
+
3
+ import os
4
+
5
+ import typer
6
+
7
+ from cli.broker.discovery import discover as discover_cmd
8
+ from cli.typer import typer_utils
9
+
10
+ from . import export, files, licenses, playback, record, scripting, signals
11
+
12
+ app = typer_utils.create_typer(rich_markup_mode="rich")
13
+
14
+
15
+ # TODO: remove this?
16
+ def cb(url: str = typer.Option(None, is_eager=False, help="Broker URL", envvar="REMOTIVE_BROKER_URL")) -> None:
17
+ # This can be used to override the --url per command, lets see if this is a better approach
18
+ if url is not None:
19
+ os.environ["REMOTIVE_BROKER_URL"] = url
20
+
21
+
22
+ # TODO: move broker commands to subcommand instead?
23
+ app.command(help="Discover brokers on this network")(discover_cmd)
24
+ app.callback()(cb)
25
+
26
+ # subcommands
27
+ app.add_typer(playback.app, name="playback", help="Manage playing recordings")
28
+ app.add_typer(record.app, name="record", help="Record data on buses")
29
+ app.add_typer(files.app, name="files", help="Upload/Download configurations and recordings")
30
+ app.add_typer(signals.app, name="signals", help="Find and subscribe to signals")
31
+ app.add_typer(export.app, name="export", help="Export to external formats")
32
+ app.add_typer(scripting.app, name="scripting", help="LUA scripting utilities")
33
+ app.add_typer(licenses.app, name="license", help="View and request license to broker")
34
+
35
+ if __name__ == "__main__":
36
+ app()
@@ -0,0 +1,43 @@
1
+ from __future__ import annotations
2
+
3
+ from time import sleep
4
+
5
+ from zeroconf import IPVersion, ServiceBrowser, ServiceStateChange, Zeroconf
6
+
7
+ from cli.utils.console import print_generic_message, print_newline
8
+
9
+
10
+ def discover() -> None:
11
+ zeroconf = Zeroconf(ip_version=IPVersion.V4Only)
12
+ services = ["_remotivebroker._tcp.local."]
13
+
14
+ print_generic_message("Looking for RemotiveBrokers on your network, press Ctrl-C to exit...")
15
+ ServiceBrowser(zeroconf, services, handlers=[on_service_state_change])
16
+
17
+ try:
18
+ while True:
19
+ sleep(0.1)
20
+ except KeyboardInterrupt:
21
+ pass
22
+ finally:
23
+ zeroconf.close()
24
+
25
+
26
+ def on_service_state_change(zeroconf: Zeroconf, service_type: str, name: str, state_change: ServiceStateChange) -> None:
27
+ """TODO: use log instead of print for debug information?"""
28
+ if state_change is ServiceStateChange.Removed:
29
+ print_generic_message(f"Service {name} was removed")
30
+
31
+ if state_change is ServiceStateChange.Updated:
32
+ print_generic_message(f"Service {name} was updated")
33
+
34
+ if state_change is ServiceStateChange.Added:
35
+ print_generic_message(f"[ {name} ]")
36
+ info = zeroconf.get_service_info(service_type, name)
37
+ if info:
38
+ for addr in info.parsed_scoped_addresses():
39
+ print_generic_message(f"RemotiveBrokerApp: http://{addr}:8080")
40
+ print_generic_message(f"RemotiveBroker http://{addr}:50051")
41
+ else:
42
+ print_generic_message(" No info")
43
+ print_newline()
@@ -7,7 +7,7 @@ from typing import Any, List
7
7
  import grpc
8
8
  import typer
9
9
 
10
- from cli.errors import ErrorPrinter
10
+ from cli.utils.console import print_generic_message, print_grpc_error, print_hint
11
11
 
12
12
  from ..typer import typer_utils
13
13
  from .lib.broker import Broker, SubscribableSignal
@@ -26,7 +26,6 @@ def influxdb(
26
26
  url: str = typer.Option(..., help="Broker URL", envvar="REMOTIVE_BROKER_URL"),
27
27
  api_key: str = typer.Option(None, help="Cloud Broker API-KEY", envvar="REMOTIVE_BROKER_API_KEY"),
28
28
  signal: List[str] = typer.Option(..., help="List of signal names to subscribe to in format namespace:signal_name"),
29
- # namespace: str = typer.Option(..., help="Cloud Broker API-KEY or access token", envvar="REMOTIVE_BROKER_API_KEY"),
30
29
  on_change_only: bool = typer.Option(default=False, help="Only get signal if value is changed"),
31
30
  output: str = typer.Option(None, help="Write results to file, defaults to stdout"),
32
31
  ) -> None:
@@ -51,6 +50,7 @@ def influxdb(
51
50
 
52
51
  """
53
52
 
53
+ # TODO: file is not properly opened using a context manager
54
54
  if output is not None:
55
55
  f = open(output, "w")
56
56
 
@@ -65,53 +65,23 @@ def influxdb(
65
65
  return
66
66
  sig: str = signals[0]["name"].rpartition(".")[-1]
67
67
  frame = signals[0]["name"].rsplit(".", 1)[0]
68
- # frame_name = signals[0]["name"].split(".")[1]
69
68
  namespace = signals[0]["namespace"]
70
69
  signals_str = ",".join(list(map(lambda s: f"{sig}={s['value']}", signals)))
71
70
  influx_lp = f"{frame},namespace={namespace} {signals_str} {round(signals[0]['timestamp_us'] * 1000)}"
72
71
  if output is not None:
73
72
  f.write(f"{influx_lp}\n")
74
73
  else:
75
- print(f"{influx_lp}")
76
-
77
- # TODO - support for csv
78
- # def csv(x):
79
- # list = list(x)
80
- # print(x)
81
- # l = list(x)
82
- # print(l)
83
- # ll=list(map(lambda s : s, l))
84
- # for s in l:
85
- # dt = datetime.fromtimestamp(s["timestamp_nanos"] / 1000000)
86
- # t=datetime.isoformat(dt)
87
- # t=rfc3339.format_millisecond(dt)
88
- # rich_rprint(len(l))
89
- # lat = (l[0])
90
- # lon = l[1]
91
- # dt = datetime.fromtimestamp(lat["timestamp_nanos"] / 1000000)
92
- # t=datetime.isoformat(dt)
93
- # t = rfc3339.format_millisecond(dt)
94
- # name = s["name"]
95
- # value = s["value"]
96
- # if output is not None:
97
- # f.write(f'coord,{lat["value"]},{lon["value"]},{t}\n')
98
- # else:
99
- # print(f'coord,{lat["value"]},{lon["value"]},{t}')
100
- # if output is not None:
101
- # f.flush()
102
- # print(x["timestamp_nanos"])
103
- # rich_rprint(json.dumps(list(x)))
74
+ # TODO: Use log instead of print for debug information?
75
+ print_generic_message(f"{influx_lp}")
104
76
 
105
77
  os_signal.signal(os_signal.SIGINT, exit_on_ctrlc)
106
78
 
107
- # print(namespace)
108
- # signals2 = list(map( lambda s: s['signal'], broker.list_signal_names2(namespace)))
109
79
  try:
110
80
 
111
81
  def to_subscribable_signal(sig: str) -> SubscribableSignal:
112
82
  arr = sig.split(":")
113
83
  if len(arr) != 2:
114
- ErrorPrinter.print_hint(f"--signal must have format namespace:signal ({sig})")
84
+ print_hint(f"--signal must have format namespace:signal ({sig})")
115
85
  sys.exit(1)
116
86
 
117
87
  return SubscribableSignal(namespace=arr[0], name=arr[1])
@@ -120,4 +90,4 @@ def influxdb(
120
90
  broker = Broker(url, api_key)
121
91
  broker.long_name_subscribe(signals_to_subscribe_to, per_frame_influx_line_protocol, on_change_only)
122
92
  except grpc.RpcError as rpc_error:
123
- ErrorPrinter.print_grpc_error(rpc_error)
93
+ print_grpc_error(rpc_error)
@@ -7,8 +7,8 @@ import grpc
7
7
  import typer
8
8
  from rich.progress import Progress, SpinnerColumn, TextColumn
9
9
 
10
- from cli.errors import ErrorPrinter
11
10
  from cli.typer import typer_utils
11
+ from cli.utils.console import print_generic_error, print_grpc_error, print_success
12
12
 
13
13
  from .lib.broker import Broker
14
14
 
@@ -23,9 +23,9 @@ def reload_configuration(
23
23
  try:
24
24
  broker = Broker(url, api_key)
25
25
  broker.reload_config()
26
- print("Configuration successfully reloaded")
26
+ print_success("Configuration reloaded")
27
27
  except grpc.RpcError as err:
28
- ErrorPrinter.print_grpc_error(err)
28
+ print_grpc_error(err)
29
29
 
30
30
 
31
31
  @app.command()
@@ -42,12 +42,12 @@ def delete(
42
42
  broker = Broker(url, api_key)
43
43
 
44
44
  if len(path) == 0:
45
- print("At least one path must be suppled")
45
+ print_generic_error("At least one path must be suppled")
46
46
  raise typer.Exit(1)
47
47
 
48
48
  broker.delete_files(path, exit_on_failure)
49
49
  except grpc.RpcError as err:
50
- ErrorPrinter.print_grpc_error(err)
50
+ print_grpc_error(err)
51
51
 
52
52
 
53
53
  @app.command()
@@ -72,12 +72,12 @@ def download(
72
72
  if output != "":
73
73
  output_file = output
74
74
  if os.path.exists(output_file):
75
- print(f"File already exist {output_file}, please use another output file name")
75
+ print_generic_error(f"File already exist {output_file}, please use another output file name")
76
76
  else:
77
77
  broker.download(path, output_file)
78
- print(f"Successfully saved {output_file}")
78
+ print_success(f"{output_file} saved")
79
79
  except grpc.RpcError as err:
80
- ErrorPrinter.print_grpc_error(err)
80
+ print_grpc_error(err)
81
81
 
82
82
 
83
83
  @app.command()
@@ -102,19 +102,19 @@ def upload(
102
102
  path = "./" ## Does not work otherwise
103
103
 
104
104
  if not os.path.exists(path):
105
- print(f"File {path} does not exist")
105
+ print_generic_error(f"File {path} does not exist")
106
106
  raise typer.Exit(1)
107
107
 
108
108
  broker = Broker(url, api_key)
109
109
 
110
110
  if os.path.isdir(path):
111
111
  broker.upload_folder(path)
112
- print(f"Successfully uploaded {path}")
112
+ print_success(f"{path} uploaded")
113
113
  else:
114
114
  output_file = os.path.basename(path)
115
115
  if output != "":
116
116
  output_file = output
117
117
  broker.upload(path, output_file)
118
- print(f"Successfully uploaded {path}")
118
+ print_success(f"{path} uploaded")
119
119
  except grpc.RpcError as err:
120
- ErrorPrinter.print_grpc_error(err)
120
+ print_grpc_error(err)
@@ -27,14 +27,11 @@ import remotivelabs.broker._generated.traffic_api_pb2 as traffic_api
27
27
  import remotivelabs.broker._generated.traffic_api_pb2_grpc as traffic_api_grpc
28
28
  import typer
29
29
  from google.protobuf.json_format import MessageToDict
30
- from rich.console import Console
31
30
 
32
31
  from cli.broker.lib.helper import act_on_scripted_signal, act_on_signal, create_channel
33
32
  from cli.broker.lib.signalcreator import SignalCreator
34
- from cli.errors import ErrorPrinter
35
33
  from cli.settings import settings
36
-
37
- err_console = Console(stderr=True)
34
+ from cli.utils.console import print_generic_error, print_hint, print_success
38
35
 
39
36
 
40
37
  @dataclass
@@ -89,7 +86,7 @@ class Broker:
89
86
  os.environ["ACCESS_TOKEN"] = "false"
90
87
  self.intercept_channel = create_channel(url, None, None)
91
88
  else:
92
- err_console.print("Option --api-key will is deprecated and will be removed. Use access access tokens by logging in with cli.")
89
+ print_hint("Option --api-key will is deprecated and will be removed. Use access access tokens by logging in with cli.")
93
90
  os.environ["ACCESS_TOKEN"] = "false"
94
91
  self.intercept_channel = create_channel(url, api_key, None)
95
92
 
@@ -103,7 +100,7 @@ class Broker:
103
100
  err_cnt = 0
104
101
  for mode in status.playbackInfo:
105
102
  if mode.playbackMode.errorMessage:
106
- print(mode.playbackMode.errorMessage)
103
+ print_generic_error(mode.playbackMode.errorMessage)
107
104
  err_cnt = err_cnt + 1
108
105
  if err_cnt > 0:
109
106
  raise typer.Exit(1)
@@ -253,7 +250,7 @@ class Broker:
253
250
  config = network_api.FramesDistributionConfig(namespace=common.NameSpace(name=namespace))
254
251
  frame_distribution_stream = self.network_stub.SubscribeToFramesDistribution(config)
255
252
  for frame in frame_distribution_stream:
256
- f = MessageToDict(frame, including_default_value_fields=True, preserving_proto_field_name=True)
253
+ f = MessageToDict(frame, preserving_proto_field_name=True)
257
254
  callback(f)
258
255
 
259
256
  def pause(self, namespace: str, path: str, silent: bool = False) -> traffic_api.PlaybackInfos:
@@ -331,10 +328,10 @@ class Broker:
331
328
 
332
329
  for r in response:
333
330
  if r["data"]:
334
- print(f"Successfully received traffic on {r['namespace']}")
331
+ print_success(f"Received traffic on {r['namespace']}")
335
332
  keep_running = False
336
333
  elif not wait_for_traffic or (not keep_running and not keep_running_during_recording):
337
- print(f"Namespace {r['namespace']} did not receive any traffic")
334
+ print_generic_error(f"Namespace {r['namespace']} did not receive any traffic")
338
335
 
339
336
  def upload(self, file: str, dest: str) -> None:
340
337
  sha256 = get_sha256(file)
@@ -343,7 +340,7 @@ class Broker:
343
340
  try:
344
341
  self.system_stub.UploadFile(upload_iterator, compression=grpc.Compression.Gzip)
345
342
  except grpc.RpcError as rpc_error:
346
- print(f"Failed to upload file - {rpc_error.details()} ({rpc_error.code()})")
343
+ print_generic_error(f"Failed to upload file - {rpc_error.details()} ({rpc_error.code()})")
347
344
  raise typer.Exit(1)
348
345
 
349
346
  def delete_files(self, path: List[str], exit_on_faliure: bool) -> None:
@@ -353,7 +350,7 @@ class Broker:
353
350
  system_api.FileDescriptions(fileDescriptions=[system_api.FileDescription(path=file.replace(ntpath.sep, posixpath.sep))])
354
351
  )
355
352
  except grpc.RpcError as rpc_error:
356
- print(f"Failed to delete file - {rpc_error.details()} ({rpc_error.code()})")
353
+ print_generic_error(f"Failed to delete file - {rpc_error.details()} ({rpc_error.code()})")
357
354
  if exit_on_faliure:
358
355
  raise typer.Exit(1)
359
356
 
@@ -374,7 +371,7 @@ class Broker:
374
371
  except grpc.RpcError as rpc_error:
375
372
  if delegate_err:
376
373
  raise rpc_error
377
- print(f"Failed to download file - {rpc_error.details()} ({rpc_error.code()})")
374
+ print_generic_error(f"Failed to download file - {rpc_error.details()} ({rpc_error.code()})")
378
375
  # There will be an empty file if the download fails so remove that one here
379
376
  os.remove(dest)
380
377
  raise typer.Exit(1)
@@ -384,11 +381,11 @@ class Broker:
384
381
  request = common.Empty()
385
382
  response = self.system_stub.ReloadConfiguration(request, timeout=60000)
386
383
  if response.errorMessage:
387
- print(f"Failed to reload config: {response.errorMessage}")
384
+ print_generic_error(f"Failed to reload config: {response.errorMessage}")
388
385
  raise typer.Exit(1)
389
386
  # br.helper.reload_configuration(system_stub=self.system_stub)
390
387
  except grpc.RpcError as rpc_error:
391
- print(f"Failed to reload configuration - {rpc_error.details()} ({rpc_error.code()})")
388
+ print_generic_error(f"Failed to reload configuration - {rpc_error.details()} ({rpc_error.code()})")
392
389
  raise typer.Exit(1)
393
390
 
394
391
  def list_namespaces(self) -> List[str]:
@@ -412,7 +409,6 @@ class Broker:
412
409
  ):
413
410
  metadata_dict = MessageToDict(
414
411
  finfo.signalInfo.metaData,
415
- including_default_value_fields=True,
416
412
  preserving_proto_field_name=True,
417
413
  )
418
414
  sig_dict = {
@@ -430,7 +426,6 @@ class Broker:
430
426
 
431
427
  metadata_dict = MessageToDict(
432
428
  sinfo.metaData,
433
- including_default_value_fields=True,
434
429
  preserving_proto_field_name=True,
435
430
  )
436
431
  sig_dict = {
@@ -485,7 +480,7 @@ class Broker:
485
480
  if ns not in existing_ns:
486
481
  ns_not_matching.append(ns)
487
482
  if len(ns_not_matching) > 0:
488
- ErrorPrinter.print_hint(f"Namespace(s) {ns_not_matching} does not exist on broker. Namespaces found on broker: {existing_ns}")
483
+ print_hint(f"Namespace(s) {ns_not_matching} does not exist on broker. Namespaces found on broker: {existing_ns}")
489
484
  sys.exit(1)
490
485
 
491
486
  available_signals = list(filter(verify_namespace, existing_signals)) # type: ignore
@@ -495,7 +490,7 @@ class Broker:
495
490
  signals_subscribed_to_but_does_not_exist = set(subscribed_signals) - set(map(lambda s: s["signal"], signals_to_subscribe_to))
496
491
 
497
492
  if len(signals_subscribed_to_but_does_not_exist) > 0:
498
- ErrorPrinter.print_hint(f"One or more signals you subscribed to does not exist {signals_subscribed_to_but_does_not_exist}")
493
+ print_hint(f"One or more signals you subscribed to does not exist {signals_subscribed_to_but_does_not_exist}")
499
494
  sys.exit(1)
500
495
 
501
496
  return list(map(lambda s: SubscribableSignal(s["signal"], s["namespace"]), signals_to_subscribe_to))
@@ -18,6 +18,8 @@ import remotivelabs.broker._generated.system_api_pb2 as system_api
18
18
  import remotivelabs.broker._generated.system_api_pb2_grpc as system_api_grpc
19
19
  from grpc_interceptor import ClientCallDetails, ClientInterceptor
20
20
 
21
+ from cli.utils.console import print_generic_error
22
+
21
23
  log = getLogger(__name__)
22
24
 
23
25
 
@@ -221,15 +223,13 @@ def act_on_signal( # noqa: PLR0913
221
223
 
222
224
  except grpc.RpcError as e:
223
225
  # Only try to cancel if cancel was not already attempted
224
- # pylint: disable=no-member
225
226
  if e.code() != grpc.StatusCode.CANCELLED:
226
227
  try:
227
228
  subscripton.cancel()
228
- print("A gRPC error occurred:")
229
- print(e)
229
+ print_generic_error("A gRPC error occurred:")
230
+ print_generic_error(str(e))
230
231
  except grpc.RpcError:
231
232
  pass
232
- # pylint: disable=protected-access, bad-except-order
233
233
  except grpc._channel._Rendezvous as err: # type:ignore[attr-defined]
234
234
  log.error(err)
235
235
  # reload, alternatively non-existing signal
@@ -266,12 +266,11 @@ def act_on_scripted_signal( # noqa: PLR0913
266
266
  except grpc.RpcError as e:
267
267
  try:
268
268
  subscription.cancel()
269
- print("A gRPC error occurred:")
270
- print(e)
269
+ print_generic_error("A gRPC error occurred:")
270
+ print_generic_error(str(e))
271
271
  except grpc.RpcError:
272
272
  pass
273
273
 
274
- # pylint: disable=protected-access, bad-except-order
275
274
  except grpc._channel._Rendezvous as err: # type:ignore[attr-defined]
276
275
  log.error(err)
277
276
  # reload, alternatively non-existing signal
@@ -7,14 +7,12 @@ from typing import Union
7
7
  import grpc
8
8
  import requests
9
9
  import typer
10
- from rich.console import Console
11
10
  from rich.progress import Progress, SpinnerColumn, TextColumn
12
11
 
13
12
  from cli.broker.lib.broker import Broker, LicenseInfo
13
+ from cli.utils.console import print_unformatted_to_stderr
14
14
  from cli.utils.rest_helper import RestHelper as Rest
15
15
 
16
- console = Console(stderr=True)
17
-
18
16
 
19
17
  class LicenseFlow:
20
18
  def describe_with_url(self, url: str) -> LicenseInfo:
@@ -35,7 +33,7 @@ class LicenseFlow:
35
33
  return b.get_license()
36
34
 
37
35
  def request_with_url_with_internet(self, url: str) -> None:
38
- console.print("This requires internet connection from your computer during the entire licensing process")
36
+ print_unformatted_to_stderr("This requires internet connection from your computer during the entire licensing process")
39
37
 
40
38
  email = LicenseFlow.__try_authenticate_and_get_email_from_cloud()
41
39
 
@@ -52,7 +50,7 @@ class LicenseFlow:
52
50
  if not apply:
53
51
  return
54
52
 
55
- console.print(
53
+ print_unformatted_to_stderr(
56
54
  ":point_right: [bold yellow]This will request a new license or use an existing license if "
57
55
  "this hardware has already been licensed[/bold yellow]"
58
56
  )
@@ -66,7 +64,7 @@ class LicenseFlow:
66
64
  with use_progress("Applying license to broker..."):
67
65
  new_license = broker_to_license.apply_license(license_data_b64)
68
66
  if new_license.valid:
69
- console.print(f":thumbsup: Successfully applied license, it remains valid until {new_license.expires}")
67
+ print_unformatted_to_stderr(f":thumbsup: Successfully applied license, it remains valid until {new_license.expires}")
70
68
 
71
69
  def request_with_hotspot(self, url: Union[str, None] = "http://192.168.4.1:50051") -> None:
72
70
  """
@@ -76,7 +74,7 @@ class LicenseFlow:
76
74
  if url is None:
77
75
  url = "http://192.168.4.1:50051"
78
76
 
79
- console.print(
77
+ print_unformatted_to_stderr(
80
78
  "Licensing a broker over its wifi hotspot will require you to switch between internet connectivity "
81
79
  "and remotivelabs-xxx wifi hotspot"
82
80
  )
@@ -95,7 +93,7 @@ class LicenseFlow:
95
93
  if not apply:
96
94
  return
97
95
 
98
- console.print(
96
+ print_unformatted_to_stderr(
99
97
  ":point_right: [bold yellow]This will request a new license or use an existing license if "
100
98
  "this hardware has already been licensed[/bold yellow]"
101
99
  )
@@ -110,7 +108,7 @@ class LicenseFlow:
110
108
  progress_label="Applying license to broker... Make sure to switch back to remotivelabs-xxx wifi hotspot",
111
109
  )
112
110
  new_license = broker_to_license.apply_license(license_data_b64)
113
- console.print(f":thumbsup: Successfully applied license, expires {new_license.expires}")
111
+ print_unformatted_to_stderr(f":thumbsup: Successfully applied license, expires {new_license.expires}")
114
112
 
115
113
  @staticmethod
116
114
  def __try_connect_to_broker(url: str, progress_label: str, on_error_progress_label: Union[str, None] = None) -> Broker:
@@ -127,9 +125,9 @@ class LicenseFlow:
127
125
  )
128
126
  time.sleep(1)
129
127
  if on_error_progress_label is None:
130
- console.print(f":white_check_mark: {progress_label}")
128
+ print_unformatted_to_stderr(f":white_check_mark: {progress_label}")
131
129
  else:
132
- console.print(f":white_check_mark: {on_error_progress_label}")
130
+ print_unformatted_to_stderr(f":white_check_mark: {on_error_progress_label}")
133
131
  return broker_to_license
134
132
 
135
133
  @staticmethod
@@ -141,7 +139,7 @@ class LicenseFlow:
141
139
  break
142
140
  except (requests.exceptions.ConnectionError, requests.exceptions.Timeout):
143
141
  time.sleep(1)
144
- console.print(":white_check_mark: Fetching user info from cloud... Make sure you are connected to internet")
142
+ print_unformatted_to_stderr(":white_check_mark: Fetching user info from cloud... Make sure you are connected to internet")
145
143
  if r is None:
146
144
  return ""
147
145
  return str(r.json()["email"])
@@ -159,7 +157,7 @@ class LicenseFlow:
159
157
  break
160
158
  except (requests.exceptions.ConnectionError, requests.exceptions.Timeout):
161
159
  time.sleep(1)
162
- console.print(f":white_check_mark: {progress_label}")
160
+ print_unformatted_to_stderr(f":white_check_mark: {progress_label}")
163
161
  return bytes(license_data_b64)
164
162
 
165
163
 
@@ -5,8 +5,8 @@ from typing import Dict, List
5
5
  import grpc
6
6
  import typer
7
7
 
8
- from cli.errors import ErrorPrinter
9
8
  from cli.typer import typer_utils
9
+ from cli.utils.console import print_generic_error, print_generic_message, print_grpc_error, print_success
10
10
 
11
11
  from .lib.broker import Broker
12
12
 
@@ -16,7 +16,7 @@ app = typer_utils.create_typer(help=help)
16
16
  def recording_and_namespace(recording: str) -> Dict[str, str]:
17
17
  splitted = recording.split("::")
18
18
  if len(splitted) != 2:
19
- print("Invalid --recording option, expected file_name::namespace")
19
+ print_generic_error("Invalid --recording option, expected file_name::namespace")
20
20
  raise typer.Exit(1)
21
21
  return {"recording": splitted[0], "namespace": splitted[1]}
22
22
 
@@ -39,10 +39,10 @@ def play(
39
39
  try:
40
40
  broker = Broker(url, api_key)
41
41
  status = broker.play(rec)
42
- print(status)
42
+ # TODO: use log instead of print for debug information?
43
+ print_generic_message(str(status))
43
44
  except grpc.RpcError as err:
44
- ErrorPrinter.print_grpc_error(err)
45
- # print(status)
45
+ print_grpc_error(err)
46
46
 
47
47
 
48
48
  @app.command()
@@ -64,9 +64,9 @@ def stop(
64
64
  try:
65
65
  broker = Broker(url, api_key)
66
66
  broker.stop_play(rec)
67
- print("Successfully stopped recording")
67
+ print_success("Recording stopped")
68
68
  except grpc.RpcError as err:
69
- ErrorPrinter.print_grpc_error(err)
69
+ print_grpc_error(err)
70
70
 
71
71
 
72
72
  @app.command()
@@ -87,9 +87,9 @@ def pause(
87
87
  try:
88
88
  broker = Broker(url, api_key)
89
89
  broker.pause_play(rec)
90
- print("Successfully paused recording")
90
+ print_success("Recording paused")
91
91
  except grpc.RpcError as err:
92
- ErrorPrinter.print_grpc_error(err)
92
+ print_grpc_error(err)
93
93
 
94
94
 
95
95
  @app.command()
@@ -115,4 +115,4 @@ def seek(
115
115
  broker = Broker(url, api_key)
116
116
  broker.seek(rec, int(seconds * 1000000))
117
117
  except grpc.RpcError as err:
118
- ErrorPrinter.print_grpc_error(err)
118
+ print_grpc_error(err)
@@ -5,8 +5,8 @@ from typing import List
5
5
  import grpc
6
6
  import typer
7
7
 
8
- from cli.errors import ErrorPrinter
9
8
  from cli.typer import typer_utils
9
+ from cli.utils.console import print_grpc_error, print_success
10
10
 
11
11
  from .lib.broker import Broker
12
12
 
@@ -24,7 +24,7 @@ def start(
24
24
  broker = Broker(url, api_key)
25
25
  broker.record_multiple(namespace, filename)
26
26
  except grpc.RpcError as rpc_error:
27
- ErrorPrinter.print_grpc_error(rpc_error)
27
+ print_grpc_error(rpc_error)
28
28
 
29
29
 
30
30
  @app.command()
@@ -37,6 +37,6 @@ def stop(
37
37
  try:
38
38
  broker = Broker(url, api_key)
39
39
  broker.stop_multiple(namespace, filename)
40
- print("Successfully stopped recording")
40
+ print_success("Recording stopped")
41
41
  except grpc.RpcError as rpc_error:
42
- ErrorPrinter.print_grpc_error(rpc_error)
42
+ print_grpc_error(rpc_error)
@@ -5,10 +5,9 @@ from string import Template
5
5
  from typing import List
6
6
 
7
7
  import typer
8
- from rich import print as rich_print
9
8
 
10
- from cli.errors import ErrorPrinter
11
9
  from cli.typer import typer_utils
10
+ from cli.utils.console import print_generic_message, print_hint
12
11
 
13
12
  app = typer_utils.create_typer(
14
13
  rich_markup_mode="rich",
@@ -20,10 +19,9 @@ app = typer_utils.create_typer(
20
19
 
21
20
  def write(signal_name: str, script: str) -> None:
22
21
  path = f"{signal_name}.lua"
23
- f = open(path, "w")
24
- f.write(script)
25
- f.close()
26
- print(f"Secret token written to {path}")
22
+ with open(path, "w") as f:
23
+ f.write(script)
24
+ print_generic_message(f"Secret token written to {path}")
27
25
 
28
26
 
29
27
  @app.command("new-script")
@@ -35,7 +33,7 @@ def new_script(
35
33
  def to_subscribable_signal(sig: str) -> tuple[str, str]:
36
34
  arr = sig.split(":")
37
35
  if len(arr) != 2:
38
- ErrorPrinter.print_hint(f"--input-signal must have format namespace:signal ({sig})")
36
+ print_hint(f"--input-signal must have format namespace:signal ({sig})")
39
37
  sys.exit(1)
40
38
  return arr[0], arr[1]
41
39
 
@@ -121,7 +119,6 @@ end
121
119
 
122
120
  script = template.substitute(
123
121
  local_signals=local_signals,
124
- # signle_input_signal=signals_to_subscribe_to[0][1], # Take one signal and use signal name in tuple
125
122
  subscribe_pattern=subscribe_pattern,
126
123
  output_signal=output_signal,
127
124
  )
@@ -129,4 +126,4 @@ end
129
126
  if save:
130
127
  write(output_signal, script)
131
128
  else:
132
- rich_print(script)
129
+ print_generic_message(script)