Files
dp/led_platform/cli.py
T

69 lines
1.8 KiB
Python

import webbrowser
import socket
import typer
import uvicorn
from led_platform.core.config import get_settings
app = typer.Typer(help="LED wall projection platform CLI.")
def _lan_base_url(port: int = 8000) -> str:
try:
with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as sock:
sock.connect(("8.8.8.8", 80))
host = sock.getsockname()[0]
except OSError:
host = "127.0.0.1"
return f"http://{host}:{port}"
@app.command()
def serve(
host: str = typer.Option(None, help="Bind host."),
port: int = typer.Option(None, help="Bind port."),
reload: bool = typer.Option(False, help="Enable uvicorn reload."),
) -> None:
settings = get_settings()
uvicorn.run(
"led_platform.main:app",
host=host or settings.app_host,
port=port or settings.app_port,
reload=reload,
)
@app.command()
def urls(
base: str = typer.Option(None, help="Controller base URL."),
) -> None:
base = base or _lan_base_url()
typer.echo(f"Admin: {base}/")
typer.echo(f"Left output: {base}/output/left")
typer.echo(f"Right output:{base}/output/right")
typer.echo(f"Health: {base}/healthz")
typer.echo(f"Sync: {base}/api/sync/status")
@app.command()
def open(
base: str = typer.Option("http://127.0.0.1:8000", help="Controller base URL."),
target: str = typer.Option("admin", help="admin, left, right, sync"),
) -> None:
targets = {
"admin": f"{base}/",
"left": f"{base}/output/left",
"right": f"{base}/output/right",
"sync": f"{base}/api/sync/status",
}
url = targets.get(target)
if not url:
raise typer.BadParameter("target must be one of: admin, left, right, sync")
webbrowser.open(url)
typer.echo(url)
if __name__ == "__main__":
app()