Plan 3: pair CLI (POST /api/pair, write config.json)
This commit is contained in:
+61
-2
@@ -1,8 +1,67 @@
|
||||
"""Pairing CLI; see Plan 3 Task 6 for the full implementation."""
|
||||
"""Pair this Pi with the backend.
|
||||
|
||||
Usage:
|
||||
python -m client.pair --backend https://backend.example.com [--code XYZ12345]
|
||||
|
||||
Called from install.sh after it prompts the user for the code.
|
||||
"""
|
||||
import argparse
|
||||
import socket
|
||||
|
||||
import requests
|
||||
|
||||
from client.config import Config, save_config
|
||||
from client.log import get_logger
|
||||
|
||||
_log = get_logger("pair")
|
||||
|
||||
CLIENT_VERSION = "0.1.0"
|
||||
|
||||
|
||||
def pair(*, backend: str, code: str | None, hostname: str) -> None:
|
||||
backend = backend.rstrip("/")
|
||||
if not code:
|
||||
code = input("Pairing code: ").strip()
|
||||
if not code:
|
||||
raise SystemExit("no pairing code supplied")
|
||||
|
||||
url = f"{backend}/api/pair"
|
||||
payload = {"code": code, "hostname": hostname, "client_version": CLIENT_VERSION}
|
||||
_log.info("POST %s code=%s hostname=%s", url, code, hostname)
|
||||
|
||||
try:
|
||||
resp = requests.post(url, json=payload, timeout=30)
|
||||
except requests.RequestException as exc:
|
||||
raise SystemExit(f"pair request failed: {exc}") from exc
|
||||
|
||||
if resp.status_code != 200:
|
||||
try:
|
||||
err = resp.json().get("error", resp.text)
|
||||
except ValueError:
|
||||
err = resp.text
|
||||
raise SystemExit(f"/api/pair returned {resp.status_code}: {err}")
|
||||
|
||||
body = resp.json()
|
||||
cfg = Config(
|
||||
device_id=str(body["device_id"]),
|
||||
device_token=str(body["device_token"]),
|
||||
backend_ws=str(body["backend_ws"]),
|
||||
)
|
||||
save_config(cfg)
|
||||
_log.info("paired device %s; config saved", cfg.device_id)
|
||||
|
||||
|
||||
def main() -> None:
|
||||
raise SystemExit("client.pair: not yet implemented (see Plan 3 Task 6).")
|
||||
parser = argparse.ArgumentParser(description="Pair this Pi with the backend.")
|
||||
parser.add_argument("--backend", required=True, help="Backend base URL (https://...)")
|
||||
parser.add_argument("--code", default=None, help="Pairing code (prompted if omitted)")
|
||||
parser.add_argument(
|
||||
"--hostname",
|
||||
default=socket.gethostname(),
|
||||
help="Hostname reported to the backend (defaults to socket.gethostname())",
|
||||
)
|
||||
args = parser.parse_args()
|
||||
pair(backend=args.backend, code=args.code, hostname=args.hostname)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
Reference in New Issue
Block a user