remotivelabs-cli 0.2.3__tar.gz → 0.3.1__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 (79) hide show
  1. {remotivelabs_cli-0.2.3 → remotivelabs_cli-0.3.1}/PKG-INFO +3 -2
  2. remotivelabs_cli-0.3.1/cli/broker/__init__.py +36 -0
  3. remotivelabs_cli-0.3.1/cli/broker/discovery.py +43 -0
  4. {remotivelabs_cli-0.2.3 → remotivelabs_cli-0.3.1}/cli/broker/export.py +6 -36
  5. {remotivelabs_cli-0.2.3 → remotivelabs_cli-0.3.1}/cli/broker/files.py +12 -12
  6. {remotivelabs_cli-0.2.3 → remotivelabs_cli-0.3.1}/cli/broker/lib/broker.py +132 -106
  7. remotivelabs_cli-0.3.1/cli/broker/lib/client.py +224 -0
  8. remotivelabs_cli-0.3.1/cli/broker/lib/helper.py +277 -0
  9. remotivelabs_cli-0.3.1/cli/broker/lib/signalcreator.py +196 -0
  10. {remotivelabs_cli-0.2.3 → remotivelabs_cli-0.3.1}/cli/broker/license_flows.py +11 -13
  11. {remotivelabs_cli-0.2.3 → remotivelabs_cli-0.3.1}/cli/broker/playback.py +10 -10
  12. {remotivelabs_cli-0.2.3 → remotivelabs_cli-0.3.1}/cli/broker/record.py +4 -4
  13. {remotivelabs_cli-0.2.3 → remotivelabs_cli-0.3.1}/cli/broker/scripting.py +6 -9
  14. {remotivelabs_cli-0.2.3 → remotivelabs_cli-0.3.1}/cli/broker/signals.py +17 -19
  15. remotivelabs_cli-0.2.3/cli/cloud/cloud_cli.py → remotivelabs_cli-0.3.1/cli/cloud/__init__.py +2 -14
  16. remotivelabs_cli-0.3.1/cli/cloud/auth/cmd.py +129 -0
  17. {remotivelabs_cli-0.2.3 → remotivelabs_cli-0.3.1}/cli/cloud/auth/login.py +42 -54
  18. remotivelabs_cli-0.3.1/cli/cloud/auth_tokens.py +139 -0
  19. {remotivelabs_cli-0.2.3 → remotivelabs_cli-0.3.1}/cli/cloud/brokers.py +5 -9
  20. {remotivelabs_cli-0.2.3 → remotivelabs_cli-0.3.1}/cli/cloud/configs.py +4 -17
  21. remotivelabs_cli-0.3.1/cli/cloud/licenses/cmd.py +14 -0
  22. {remotivelabs_cli-0.2.3 → remotivelabs_cli-0.3.1}/cli/cloud/organisations.py +12 -17
  23. {remotivelabs_cli-0.2.3 → remotivelabs_cli-0.3.1}/cli/cloud/projects.py +3 -3
  24. {remotivelabs_cli-0.2.3 → remotivelabs_cli-0.3.1}/cli/cloud/recordings.py +35 -61
  25. {remotivelabs_cli-0.2.3 → remotivelabs_cli-0.3.1}/cli/cloud/recordings_playback.py +22 -22
  26. {remotivelabs_cli-0.2.3 → remotivelabs_cli-0.3.1}/cli/cloud/resumable_upload.py +6 -6
  27. {remotivelabs_cli-0.2.3 → remotivelabs_cli-0.3.1}/cli/cloud/service_account_tokens.py +4 -3
  28. {remotivelabs_cli-0.2.3 → remotivelabs_cli-0.3.1}/cli/cloud/storage/cmd.py +2 -3
  29. {remotivelabs_cli-0.2.3 → remotivelabs_cli-0.3.1}/cli/cloud/storage/copy.py +2 -1
  30. {remotivelabs_cli-0.2.3 → remotivelabs_cli-0.3.1}/cli/connect/connect.py +4 -4
  31. {remotivelabs_cli-0.2.3 → remotivelabs_cli-0.3.1}/cli/connect/protopie/protopie.py +22 -30
  32. {remotivelabs_cli-0.2.3 → remotivelabs_cli-0.3.1}/cli/remotive.py +16 -26
  33. {remotivelabs_cli-0.2.3 → remotivelabs_cli-0.3.1}/cli/settings/__init__.py +1 -2
  34. {remotivelabs_cli-0.2.3 → remotivelabs_cli-0.3.1}/cli/settings/config_file.py +2 -0
  35. remotivelabs_cli-0.3.1/cli/settings/core.py +322 -0
  36. {remotivelabs_cli-0.2.3 → remotivelabs_cli-0.3.1}/cli/settings/migration/migrate_config_file.py +13 -6
  37. {remotivelabs_cli-0.2.3 → remotivelabs_cli-0.3.1}/cli/settings/migration/migration_tools.py +6 -4
  38. {remotivelabs_cli-0.2.3 → remotivelabs_cli-0.3.1}/cli/settings/state_file.py +12 -4
  39. {remotivelabs_cli-0.2.3 → remotivelabs_cli-0.3.1}/cli/tools/can/can.py +4 -7
  40. remotivelabs_cli-0.3.1/cli/topology/__init__.py +3 -0
  41. remotivelabs_cli-0.3.1/cli/topology/cmd.py +79 -0
  42. remotivelabs_cli-0.3.1/cli/topology/start_trial.py +105 -0
  43. {remotivelabs_cli-0.2.3 → remotivelabs_cli-0.3.1}/cli/typer/typer_utils.py +3 -6
  44. remotivelabs_cli-0.3.1/cli/utils/console.py +61 -0
  45. {remotivelabs_cli-0.2.3 → remotivelabs_cli-0.3.1}/cli/utils/rest_helper.py +33 -31
  46. {remotivelabs_cli-0.2.3 → remotivelabs_cli-0.3.1}/cli/utils/versions.py +7 -19
  47. {remotivelabs_cli-0.2.3 → remotivelabs_cli-0.3.1}/pyproject.toml +3 -2
  48. remotivelabs_cli-0.2.3/cli/broker/brokers.py +0 -93
  49. remotivelabs_cli-0.2.3/cli/cloud/auth/cmd.py +0 -88
  50. remotivelabs_cli-0.2.3/cli/cloud/auth_tokens.py +0 -346
  51. remotivelabs_cli-0.2.3/cli/errors.py +0 -44
  52. remotivelabs_cli-0.2.3/cli/settings/core.py +0 -322
  53. remotivelabs_cli-0.2.3/cli/topology/cmd.py +0 -102
  54. {remotivelabs_cli-0.2.3 → remotivelabs_cli-0.3.1}/LICENSE +0 -0
  55. {remotivelabs_cli-0.2.3 → remotivelabs_cli-0.3.1}/README.md +0 -0
  56. {remotivelabs_cli-0.2.3 → remotivelabs_cli-0.3.1}/cli/.DS_Store +0 -0
  57. {remotivelabs_cli-0.2.3 → remotivelabs_cli-0.3.1}/cli/__init__.py +0 -0
  58. {remotivelabs_cli-0.2.3 → remotivelabs_cli-0.3.1}/cli/api/cloud/tokens.py +0 -0
  59. {remotivelabs_cli-0.2.3 → remotivelabs_cli-0.3.1}/cli/broker/lib/__about__.py +0 -0
  60. {remotivelabs_cli-0.2.3 → remotivelabs_cli-0.3.1}/cli/broker/licenses.py +0 -0
  61. {remotivelabs_cli-0.2.3 → remotivelabs_cli-0.3.1}/cli/cloud/auth/__init__.py +0 -0
  62. {remotivelabs_cli-0.2.3/cli/cloud → remotivelabs_cli-0.3.1/cli/cloud/licenses}/__init__.py +0 -0
  63. {remotivelabs_cli-0.2.3 → remotivelabs_cli-0.3.1}/cli/cloud/sample_recordings.py +0 -0
  64. {remotivelabs_cli-0.2.3 → remotivelabs_cli-0.3.1}/cli/cloud/service_accounts.py +0 -0
  65. {remotivelabs_cli-0.2.3 → remotivelabs_cli-0.3.1}/cli/cloud/storage/__init__.py +0 -0
  66. {remotivelabs_cli-0.2.3 → remotivelabs_cli-0.3.1}/cli/cloud/storage/uri_or_path.py +0 -0
  67. {remotivelabs_cli-0.2.3 → remotivelabs_cli-0.3.1}/cli/cloud/uri.py +0 -0
  68. {remotivelabs_cli-0.2.3 → remotivelabs_cli-0.3.1}/cli/connect/__init__.py +0 -0
  69. {remotivelabs_cli-0.2.3 → remotivelabs_cli-0.3.1}/cli/settings/migration/__init__.py +0 -0
  70. {remotivelabs_cli-0.2.3 → remotivelabs_cli-0.3.1}/cli/settings/migration/migrate_all_token_files.py +0 -0
  71. {remotivelabs_cli-0.2.3 → remotivelabs_cli-0.3.1}/cli/settings/migration/migrate_legacy_dirs.py +0 -0
  72. {remotivelabs_cli-0.2.3 → remotivelabs_cli-0.3.1}/cli/settings/migration/migrate_token_file.py +0 -0
  73. {remotivelabs_cli-0.2.3 → remotivelabs_cli-0.3.1}/cli/settings/token_file.py +0 -0
  74. {remotivelabs_cli-0.2.3 → remotivelabs_cli-0.3.1}/cli/tools/__init__.py +0 -0
  75. {remotivelabs_cli-0.2.3 → remotivelabs_cli-0.3.1}/cli/tools/can/__init__.py +0 -0
  76. {remotivelabs_cli-0.2.3 → remotivelabs_cli-0.3.1}/cli/tools/tools.py +0 -0
  77. {remotivelabs_cli-0.2.3 → remotivelabs_cli-0.3.1}/cli/typer/__init__.py +0 -0
  78. {remotivelabs_cli-0.2.3 → remotivelabs_cli-0.3.1}/cli/utils/__init__.py +0 -0
  79. {remotivelabs_cli-0.2.3 → remotivelabs_cli-0.3.1}/cli/utils/time.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: remotivelabs-cli
3
- Version: 0.2.3
3
+ Version: 0.3.1
4
4
  Summary: CLI for operating RemotiveCloud and RemotiveBroker
5
5
  Author: Johan Rask
6
6
  Author-email: johan.rask@remotivelabs.com
@@ -20,7 +20,8 @@ Requires-Dist: pydantic (>=2.11.7,<3.0.0)
20
20
  Requires-Dist: pyjwt (>=2.6,<3.0)
21
21
  Requires-Dist: python-can (>=4.3.1)
22
22
  Requires-Dist: python-socketio (>=4.6.1)
23
- Requires-Dist: remotivelabs-broker (>=0.1.17,<0.2.0)
23
+ Requires-Dist: remotivelabs-broker (>=0.9.1,<0.10.0)
24
+ Requires-Dist: requests (>=2.32.4,<3.0.0)
24
25
  Requires-Dist: rich (>=13.7.0,<13.8.0)
25
26
  Requires-Dist: trogon (>=0.5.0)
26
27
  Requires-Dist: typer (==0.12.5)
@@ -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)