Source code for uniqc.gateway.config

"""Gateway server configuration — reads gateway.port/host from config.yaml."""

from __future__ import annotations

import ipaddress
from typing import Any

from uniqc import config as _base_config

# Gateway-specific default values
DEFAULT_GATEWAY_PORT = 18765
DEFAULT_GATEWAY_HOST = "127.0.0.1"


[docs] def validate_loopback_host(host: str) -> str: """Return a normalized loopback host or raise ``ValueError``.""" normalized = host.strip() if normalized.startswith("[") and normalized.endswith("]"): normalized = normalized[1:-1] if normalized.lower().rstrip(".") == "localhost": return "localhost" try: address = ipaddress.ip_address(normalized) except ValueError as exc: raise ValueError(f"Gateway host '{host}' is not allowed; use localhost or a loopback IP address.") from exc if not address.is_loopback: raise ValueError(f"Gateway host '{host}' is not allowed; use localhost or a loopback IP address.") return str(address)
[docs] def load_gateway_config(*, host_override: str | None = None) -> dict[str, Any]: """Load the [gateway] section from ~/.uniqc/config.yaml. If the key is absent the defaults apply: port: 18765 host: 127.0.0.1 (localhost-only for security) """ cfg = _base_config.load_config() gateway_cfg = cfg.get("gateway", {}) host = host_override if host_override is not None else gateway_cfg.get("host", DEFAULT_GATEWAY_HOST) return { "port": gateway_cfg.get("port", DEFAULT_GATEWAY_PORT), "host": validate_loopback_host(str(host)), }
[docs] def save_gateway_config(*, port: int | None = None, host: str | None = None) -> None: """Persist gateway settings into config.yaml, preserving all other keys.""" if host is not None: host = validate_loopback_host(host) cfg = _base_config.load_config() if "gateway" not in cfg: cfg["gateway"] = {} if port is not None: cfg["gateway"]["port"] = port if host is not None: cfg["gateway"]["host"] = host _base_config.save_config(cfg)