Coverage for core / src / sensorkit / cli / utils.py: 0%
41 statements
« prev ^ index » next coverage.py v7.13.5, created at 2026-09-02 00:03 +0000
« prev ^ index » next coverage.py v7.13.5, created at 2026-09-02 00:03 +0000
1# SPDX-License-Identifier: Apache-2.0
2import functools
3from contextlib import contextmanager
4from typing import Any, Callable
6import asyncclick as click
7from rich.console import Console
9from sensorkit.api.entrypoint import ShutdownSignal
11console = Console()
14def common_options(f: Callable[..., Any]) -> Callable[..., Any]:
15 """Decorator to add common SensorKit options to a command."""
16 # Placeholder for common options like --config, --log-level etc.
17 # For now, we can just return f
18 return f
21def entity_option(default: str | None = None, required: bool = False, help: str = "Entity name"):
22 """Standardized entity option."""
23 return click.option("-e", "--entity", default=default, required=required, help=help)
26@contextmanager
27def report_errors():
28 from sensorkit.backend.base import BackendError, KVError
29 from sensorkit.backend.lease import LeaseUnavailableError
31 try:
32 yield
33 except* ShutdownSignal:
34 # Fall through to normal shutdown.
35 pass
36 except* KVError as eg:
37 console.print(f"[red]Error:[/red] Configuration or state error: {eg.exceptions[0]}")
38 raise click.Abort() from eg
39 except* LeaseUnavailableError as eg:
40 console.print("[red]Error:[/red] Service or entity is already running!")
41 raise click.Abort() from eg
42 except* BackendError as eg:
43 console.print(f"[red]Error:[/red] Backend unavailable: {eg.exceptions[0]}")
44 raise click.Abort() from eg
45 except* Exception as eg:
46 for e in eg.exceptions:
47 console.print(f"[red]Unexpected {type(e).__name__}[/red]")
49 console.print_exception()
50 raise click.Abort() from eg
53def with_kit(f: Callable[..., Any]) -> Callable[..., Any]:
54 """Decorator that provides a 'kit' instance to the command and handles errors."""
56 @functools.wraps(f)
57 async def wrapper(*args, **kwargs):
58 from sensorkit.api.bootstrap import connect
60 with report_errors():
61 kit = await connect()
62 return await f(kit, *args, **kwargs)
64 return wrapper