"""ReinLoop cloud-server endpoint configuration shared by core modules.""" import os import threading import time import requests from license_utils import get_verified_license base_url = os.environ.get( "REINLOOP_SERVER_URL", "https://ReinLoop.dominatedconvergence.com", ).rstrip("/") server_api_url = os.environ.get( "REINLOOP_API_URL", base_url, ) # Compatibility alias used by existing modules. It points to the ReinLoop # Express server API, not a cloud-function endpoint. data_record_url = server_api_url device_api_url = f"{server_api_url.rstrip('/')}/device" _license = get_verified_license() _license_device_id = (_license or {}).get("device_id", "").strip() _environment_device_id = os.environ.get("REINLOOP_DEVICE_ID", "").strip() if _license_device_id and _environment_device_id and _license_device_id != _environment_device_id: raise RuntimeError("REINLOOP_DEVICE_ID 与许可证 device_id 不一致") the_folder = _license_device_id or _environment_device_id or "local-test-device" if not the_folder: raise RuntimeError("设备 ID 不能为空") _DEVICE_TOKEN = None _DEVICE_TOKEN_EXPIRES_AT_MS = 0 _DEVICE_TOKEN_LOCK = threading.Lock() def _current_license_context(): payload = get_verified_license() or {} license_id = str(payload.get("license_id") or "").strip() device_id = str(payload.get("device_id") or _environment_device_id or the_folder).strip() return license_id, device_id def _ensure_device_token(timeout=10): global _DEVICE_TOKEN, _DEVICE_TOKEN_EXPIRES_AT_MS with _DEVICE_TOKEN_LOCK: now_ms = int(time.time() * 1000) if _DEVICE_TOKEN and _DEVICE_TOKEN_EXPIRES_AT_MS - now_ms > 30_000: return _DEVICE_TOKEN license_id, device_id = _current_license_context() if not license_id: raise RuntimeError("许可证未就绪,无法获取 deviceToken") response = requests.post(device_api_url, json={ "type": "deviceAuth", "licenseId": license_id, "deviceId": device_id, }, timeout=timeout) response.raise_for_status() result = response.json() if not result.get("success"): raise RuntimeError(result.get("errMsg") or "设备鉴权失败") _DEVICE_TOKEN = str(result.get("deviceToken") or "").strip() _DEVICE_TOKEN_EXPIRES_AT_MS = int(result.get("expiresAtMs") or 0) if not _DEVICE_TOKEN or _DEVICE_TOKEN_EXPIRES_AT_MS <= now_ms: raise RuntimeError("设备鉴权返回了无效 deviceToken") return _DEVICE_TOKEN def device_post(payload, timeout=10): """Call the device-scoped API route with an auto-renewed device token.""" token = _ensure_device_token(timeout=timeout) request_payload = {**payload, "deviceToken": token} response = requests.post(device_api_url, json=request_payload, timeout=timeout) response.raise_for_status() result = response.json() if result.get("success"): return result if result.get("errCode") in {"DEVICE_TOKEN_EXPIRED", "DEVICE_TOKEN_INVALID"}: with _DEVICE_TOKEN_LOCK: global _DEVICE_TOKEN, _DEVICE_TOKEN_EXPIRES_AT_MS _DEVICE_TOKEN = None _DEVICE_TOKEN_EXPIRES_AT_MS = 0 token = _ensure_device_token(timeout=timeout) response = requests.post(device_api_url, json={**payload, "deviceToken": token}, timeout=timeout) response.raise_for_status() result = response.json() return result