Files
Assistant/client/config.py
T

50 lines
1.5 KiB
Python

"""Read / write the device config file at ~/assistant/state/config.json."""
import json
import os
from dataclasses import asdict, dataclass
from pathlib import Path
class ConfigMissingError(RuntimeError):
"""Raised when config.json is missing or malformed."""
@dataclass(frozen=True)
class Config:
device_id: str
device_token: str
backend_ws: str
def config_path() -> Path:
return Path(os.environ["HOME"]) / "assistant" / "state" / "config.json"
def load_config() -> Config:
path = config_path()
if not path.exists():
raise ConfigMissingError(f"{path} not found; run `python -m client.pair` first")
try:
raw = json.loads(path.read_text())
except json.JSONDecodeError as exc:
raise ConfigMissingError(f"{path} is not valid JSON: {exc}") from exc
try:
return Config(
device_id=str(raw["device_id"]),
device_token=str(raw["device_token"]),
backend_ws=str(raw["backend_ws"]),
)
except KeyError as exc:
raise ConfigMissingError(f"{path} missing field: {exc}") from exc
def save_config(cfg: Config) -> None:
path = config_path()
path.parent.mkdir(parents=True, exist_ok=True)
# Write to a temp file then atomically rename, so a partial write never
# leaves a half-baked config on disk.
tmp = path.with_suffix(".json.tmp")
tmp.write_text(json.dumps(asdict(cfg), indent=2) + "\n")
os.chmod(tmp, 0o600)
os.replace(tmp, path)