lookout-cli 3.2.0__tar.gz → 3.3.0__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.
Files changed (29) hide show
  1. {lookout_cli-3.2.0 → lookout_cli-3.3.0}/PKG-INFO +1 -1
  2. {lookout_cli-3.2.0 → lookout_cli-3.3.0}/lookout_cli/cli.py +3 -0
  3. {lookout_cli-3.2.0 → lookout_cli-3.3.0}/lookout_cli/docker/docker-compose.yaml +1 -0
  4. {lookout_cli-3.2.0 → lookout_cli-3.3.0}/lookout_cli/groups/base.py +96 -32
  5. {lookout_cli-3.2.0 → lookout_cli-3.3.0}/lookout_cli/helpers.py +18 -6
  6. {lookout_cli-3.2.0 → lookout_cli-3.3.0}/lookout_cli.egg-info/PKG-INFO +1 -1
  7. {lookout_cli-3.2.0 → lookout_cli-3.3.0}/pyproject.toml +1 -1
  8. {lookout_cli-3.2.0 → lookout_cli-3.3.0}/README.md +0 -0
  9. {lookout_cli-3.2.0 → lookout_cli-3.3.0}/lookout_cli/__init__.py +0 -0
  10. {lookout_cli-3.2.0 → lookout_cli-3.3.0}/lookout_cli/auth_helpers.py +0 -0
  11. {lookout_cli-3.2.0 → lookout_cli-3.3.0}/lookout_cli/banner.py +0 -0
  12. {lookout_cli-3.2.0 → lookout_cli-3.3.0}/lookout_cli/docker/docker-compose.cache.yaml +0 -0
  13. {lookout_cli-3.2.0 → lookout_cli-3.3.0}/lookout_cli/docker/docker-compose.dev.yaml +0 -0
  14. {lookout_cli-3.2.0 → lookout_cli-3.3.0}/lookout_cli/docker/docker-compose.jetson.yaml +0 -0
  15. {lookout_cli-3.2.0 → lookout_cli-3.3.0}/lookout_cli/docker/docker-compose.network-host.yaml +0 -0
  16. {lookout_cli-3.2.0 → lookout_cli-3.3.0}/lookout_cli/docker/docker-compose.network-proxy.yaml +0 -0
  17. {lookout_cli-3.2.0 → lookout_cli-3.3.0}/lookout_cli/docker/docker-compose.prod.yaml +0 -0
  18. {lookout_cli-3.2.0 → lookout_cli-3.3.0}/lookout_cli/groups/__init__.py +0 -0
  19. {lookout_cli-3.2.0 → lookout_cli-3.3.0}/lookout_cli/groups/model.py +0 -0
  20. {lookout_cli-3.2.0 → lookout_cli-3.3.0}/lookout_cli/groups/setup.py +0 -0
  21. {lookout_cli-3.2.0 → lookout_cli-3.3.0}/lookout_cli/test/lookout_cli_test.py +0 -0
  22. {lookout_cli-3.2.0 → lookout_cli-3.3.0}/lookout_cli.egg-info/SOURCES.txt +0 -0
  23. {lookout_cli-3.2.0 → lookout_cli-3.3.0}/lookout_cli.egg-info/dependency_links.txt +0 -0
  24. {lookout_cli-3.2.0 → lookout_cli-3.3.0}/lookout_cli.egg-info/entry_points.txt +0 -0
  25. {lookout_cli-3.2.0 → lookout_cli-3.3.0}/lookout_cli.egg-info/requires.txt +0 -0
  26. {lookout_cli-3.2.0 → lookout_cli-3.3.0}/lookout_cli.egg-info/top_level.txt +0 -0
  27. {lookout_cli-3.2.0 → lookout_cli-3.3.0}/lookout_cli.egg-info/zip-safe +0 -0
  28. {lookout_cli-3.2.0 → lookout_cli-3.3.0}/setup.cfg +0 -0
  29. {lookout_cli-3.2.0 → lookout_cli-3.3.0}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: lookout_cli
3
- Version: 3.2.0
3
+ Version: 3.3.0
4
4
  Summary: A CLI for interacting with Lookout+
5
5
  Author-email: Greenroom Robotics <team@greenroomrobotics.com>
6
6
  Maintainer-email: David Revay <david.revay@greenroomrobotics.com>
@@ -24,6 +24,9 @@ def cli():
24
24
  lookout_cli.add_command(base.upgrade)
25
25
  lookout_cli.add_command(base.down)
26
26
  lookout_cli.add_command(base.up)
27
+ lookout_cli.add_command(base.logs)
28
+ lookout_cli.add_command(base.restart)
29
+ lookout_cli.add_command(base.install)
27
30
  lookout_cli.add_command(base.configure)
28
31
  base.configure.add_command(base.configure_all)
29
32
  base.configure.add_command(base.configure_auth)
@@ -53,6 +53,7 @@ services:
53
53
  - /tmp:/tmp
54
54
  - ~/.config/greenroom:/home/ros/.config/greenroom
55
55
  - ${LOOKOUT_LOG_DIR:-/tmp/log}:/home/ros/.ros/log
56
+ - ${LOOKOUT_RECORDING_DIR:-/tmp/rosbags}:/home/ros/rosbags
56
57
  command: ${LOOKOUT_GREENSTREAM_COMMAND:-tail -f /dev/null}
57
58
  privileged: true
58
59
  ipc: host
@@ -16,12 +16,12 @@ from lookout_cli.helpers import (
16
16
  get_installer,
17
17
  get_project_root,
18
18
  get_version,
19
+ is_dev_version,
19
20
  make_dir_set_permission,
21
+ maybe_ignore_prod,
20
22
  )
21
23
  from lookout_config import get_config_io
22
24
  from lookout_config.types import (
23
- Discovery,
24
- DiscoverySimple,
25
25
  GeolocationMode,
26
26
  LogLevel,
27
27
  LookoutConfig,
@@ -131,15 +131,6 @@ def log_config(config: LookoutConfig):
131
131
  )
132
132
 
133
133
 
134
- def get_discovery_range(discovery: Discovery) -> str:
135
- if isinstance(discovery, DiscoverySimple):
136
- if discovery.discovery_range == "localhost":
137
- return "LOCALHOST"
138
- elif discovery.discovery_range == "subnet":
139
- return "SUBNET"
140
- return "SYSTEM_DEFAULT"
141
-
142
-
143
134
  def set_initial_env(config_dir: str):
144
135
  version = get_version()
145
136
  os.environ["LOOKOUT_CONFIG_DIR"] = config_dir
@@ -162,17 +153,11 @@ def set_env_from_config(config: LookoutConfig):
162
153
  os.environ["LOOKOUT_PROXY_HTTPS_PORT"] = str(config.proxy.https_port)
163
154
 
164
155
  # Middleware settings
165
- os.environ["ROS_DOMAIN_ID"] = (
166
- str(config.discovery.ros_domain_id) if config.discovery.type in ["simple", "easy"] else "0"
167
- )
168
- os.environ["ROS_AUTOMATIC_DISCOVERY_RANGE"] = get_discovery_range(config.discovery)
156
+ os.environ["ROS_DOMAIN_ID"] = str(config.discovery.ros_domain_id)
157
+ os.environ["ROS_AUTOMATIC_DISCOVERY_RANGE"] = "SUBNET"
169
158
  os.environ["RMW_IMPLEMENTATION"] = (
170
159
  "rmw_zenoh_cpp" if config.discovery.type == "zenoh" else "rmw_fastrtps_cpp"
171
160
  )
172
- if config.discovery.type == "zenoh":
173
- os.environ[
174
- "ZENOH_CONFIG_OVERRIDE"
175
- ] = f'connect/endpoints=["tcp/{config.discovery.discovery_server_ip}:7447"]'
176
161
 
177
162
  # Launch commands
178
163
  if config.prod:
@@ -197,11 +182,6 @@ def set_env_from_config(config: LookoutConfig):
197
182
  is_flag=True,
198
183
  help="Should we rebuild the docker containers? Default: False",
199
184
  )
200
- @click.option(
201
- "--pull",
202
- help="Should we do a docker pull",
203
- is_flag=True,
204
- )
205
185
  @config_dir_option
206
186
  @click.argument(
207
187
  "services",
@@ -211,14 +191,15 @@ def set_env_from_config(config: LookoutConfig):
211
191
  )
212
192
  def up(
213
193
  build: bool,
214
- pull: bool,
215
194
  config_dir: str,
216
195
  services: List[str],
217
196
  ):
218
197
  """Starts lookout"""
219
198
  set_initial_env(config_dir)
199
+ dev_mode = is_dev_version()
220
200
 
221
201
  config = get_config_io().read()
202
+ config.prod = maybe_ignore_prod(dev_mode, config.prod)
222
203
  log_config(config)
223
204
 
224
205
  if config.prod and build:
@@ -242,9 +223,7 @@ def up(
242
223
  services_list = list(services) if services else None
243
224
 
244
225
  docker = _get_docker_client(prod=config.prod, proxy=config.proxy.enabled)
245
- docker.compose.up(
246
- services_list, detach=True, build=build, pull="always" if pull else "missing"
247
- )
226
+ docker.compose.up(services_list, detach=True, build=build)
248
227
 
249
228
  ui_host = (
250
229
  f"https://localhost:{config.proxy.https_port} and http://localhost:{config.proxy.http_port}"
@@ -260,11 +239,97 @@ def up(
260
239
  def down(config_dir: str, args: List[str]):
261
240
  """Stops lookout"""
262
241
  set_initial_env(config_dir)
242
+ dev_mode = is_dev_version()
243
+
244
+ config = get_config_io().read()
245
+ config.prod = maybe_ignore_prod(dev_mode, config.prod)
246
+
247
+ docker = _get_docker_client(prod=config.prod, proxy=config.proxy.enabled)
248
+ docker.compose.down(timeout=20)
249
+
250
+
251
+ @click.command(name="logs")
252
+ @click.option("--tail", "-n", type=int, default=None, help="Number of lines to show from the end")
253
+ @click.option("--timestamps", "-t", is_flag=True, help="Show timestamps")
254
+ @click.option(
255
+ "--since",
256
+ type=str,
257
+ default=None,
258
+ help="Show logs since timestamp (e.g. 2021-01-01T00:00:00) or relative (e.g. 42m for 42 minutes)",
259
+ )
260
+ @config_dir_option
261
+ @click.argument(
262
+ "services",
263
+ required=False,
264
+ nargs=-1,
265
+ type=click.Choice(SERVICES),
266
+ )
267
+ def logs(tail: int, timestamps: bool, since: str, config_dir: str, services: List[str]):
268
+ """Follow log output from containers"""
269
+ set_initial_env(config_dir)
270
+ config = get_config_io().read()
271
+ docker = _get_docker_client(prod=config.prod, proxy=config.proxy.enabled)
272
+ services_list = list(services)
273
+
274
+ output = docker.compose.logs(
275
+ services=services_list,
276
+ follow=True,
277
+ tail=str(tail) if tail else "all",
278
+ timestamps=timestamps,
279
+ since=since,
280
+ stream=True,
281
+ )
282
+ for _, stream_content in output:
283
+ print(stream_content.decode("utf-8"), end="", flush=True) # type: ignore
284
+
285
+
286
+ @click.command(name="restart")
287
+ @click.option("--timeout", "-t", type=int, default=20, help="Timeout in seconds (default: 20)")
288
+ @config_dir_option
289
+ @click.argument(
290
+ "services",
291
+ required=False,
292
+ nargs=-1,
293
+ type=click.Choice(SERVICES),
294
+ )
295
+ def restart(timeout: int, config_dir: str, services: List[str]):
296
+ """Restart containers"""
297
+ set_initial_env(config_dir)
298
+ config = get_config_io().read()
299
+ docker = _get_docker_client(prod=config.prod, proxy=config.proxy.enabled)
300
+ services_list = list(services) or None
301
+ docker.compose.restart(services=services_list, timeout=timeout)
302
+
303
+
304
+ @click.command(name="install")
305
+ @config_dir_option
306
+ def install(config_dir: str):
307
+ """Install Lookout (pull Docker images)"""
308
+ set_initial_env(config_dir)
309
+ dev_mode = is_dev_version()
263
310
 
264
311
  config = get_config_io().read()
312
+ config.prod = maybe_ignore_prod(dev_mode, config.prod)
313
+ set_env_from_config(config)
265
314
 
266
315
  docker = _get_docker_client(prod=config.prod, proxy=config.proxy.enabled)
267
- docker.compose.down()
316
+ try:
317
+ docker.compose.pull(
318
+ [
319
+ "lookout_core",
320
+ "lookout_ui",
321
+ "lookout_greenstream",
322
+ "lookout_docs",
323
+ "lookout_proxy",
324
+ ]
325
+ )
326
+ except Exception:
327
+ click.echo(
328
+ click.style(
329
+ "Failed to pull Lookout images. Have you run `lookout authenticate`?",
330
+ fg="yellow",
331
+ )
332
+ )
268
333
 
269
334
 
270
335
  @click.command(name="build")
@@ -357,9 +422,7 @@ def generate(config_dir: str, launch_parameters: bool):
357
422
  set_initial_env(config_dir)
358
423
  config = get_config_io().read()
359
424
 
360
- os.environ["ROS_DOMAIN_ID"] = (
361
- str(config.discovery.ros_domain_id) if config.discovery.type in ["simple", "easy"] else "0"
362
- )
425
+ os.environ["ROS_DOMAIN_ID"] = str(config.discovery.ros_domain_id)
363
426
  docker = _get_docker_client()
364
427
  if launch_parameters:
365
428
  click.echo(click.style("Generating models from launch params...", fg="green"))
@@ -414,6 +477,7 @@ def upgrade(version: str):
414
477
  call(f"{installer} install --upgrade lookout-cli")
415
478
 
416
479
  click.echo(click.style("Upgrade of Lookout CLI complete.", fg="green"))
480
+ click.echo(click.style("Run `lookout install` to pull updated Docker images.", fg="green"))
417
481
 
418
482
 
419
483
  @click.command(name="authenticate")
@@ -5,8 +5,8 @@ from pathlib import Path
5
5
  from typing import Any, Dict, List, Optional
6
6
 
7
7
  import click
8
- import pkg_resources
9
8
  import yaml
9
+ from importlib.metadata import version as pkg_version
10
10
  from python_on_whales.utils import ValidPath
11
11
 
12
12
 
@@ -26,10 +26,10 @@ def make_dir_set_permission(path: Path, permission=0o777) -> Path:
26
26
 
27
27
  def get_version():
28
28
  """version is latest if it is a dev version otherwise it is the CLI version"""
29
- version = pkg_resources.require("lookout-cli")[0].version
30
- if version == "0.0.0":
31
- version = "latest"
32
- return version
29
+ v = pkg_version("lookout-cli")
30
+ if v == "0.0.0":
31
+ return "latest"
32
+ return v
33
33
 
34
34
 
35
35
  def is_dev_version():
@@ -38,7 +38,7 @@ def is_dev_version():
38
38
 
39
39
  if os.environ.get("LOOKOUT_CLI_DEV_MODE") == "true":
40
40
  return True
41
- return pkg_resources.require("lookout_cli")[0].version == "0.0.0"
41
+ return pkg_version("lookout-cli") == "0.0.0"
42
42
 
43
43
 
44
44
  def docker_compose_path(path: str) -> Path:
@@ -180,6 +180,18 @@ def docker_manifest(
180
180
  click.echo(click.style(f"✓ Created manifests for {image}", fg="green"))
181
181
 
182
182
 
183
+ def maybe_ignore_prod(dev_mode: bool, prod: bool):
184
+ """Raise an error if prod=false in non-dev mode"""
185
+ if dev_mode:
186
+ return prod
187
+ if prod is False:
188
+ raise click.ClickException(
189
+ "prod=false is not supported in production installs. Source code is required for "
190
+ "development mode. Please update your config file to set prod: true."
191
+ )
192
+ return True
193
+
194
+
183
195
  def generate_sboms(
184
196
  version: str,
185
197
  images: List[str],
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: lookout_cli
3
- Version: 3.2.0
3
+ Version: 3.3.0
4
4
  Summary: A CLI for interacting with Lookout+
5
5
  Author-email: Greenroom Robotics <team@greenroomrobotics.com>
6
6
  Maintainer-email: David Revay <david.revay@greenroomrobotics.com>
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "lookout_cli"
7
- version = "3.2.0"
7
+ version = "3.3.0"
8
8
  description = "A CLI for interacting with Lookout+"
9
9
  readme = "README.md"
10
10
  license = {text = "Copyright (C) 2025, Greenroom Robotics"}
File without changes
File without changes
File without changes