import time import httpx # alembic rides gluetun's network namespace (network_mode: service:gluetun) # specifically so sldl's Soulseek traffic stays VPN-routed -- this is the # dashboard's confidence check that it's actually working: the container's # own outbound IP should be the VPN's, not the home connection's. Cached # in-process (no DB row, no job history) since it's a lightweight external # check, not something worth tracking over time. _CACHE_TTL_SECONDS = 600 _cache: dict = {"ip": None, "checked_at": 0.0, "error": None} def public_ip() -> dict: now = time.time() if _cache["ip"] is not None and now - _cache["checked_at"] < _CACHE_TTL_SECONDS: return dict(_cache) try: resp = httpx.get("https://api.ipify.org", timeout=5.0) resp.raise_for_status() _cache["ip"] = resp.text.strip() _cache["error"] = None except Exception as exc: _cache["error"] = str(exc) # Keep the last-known-good ip (if any) rather than blanking it -- # a transient fetch failure shouldn't make the dashboard look like # the VPN dropped when it's actually just ipify being slow. _cache["checked_at"] = now return dict(_cache)