"""Crea un usuario en la API de administracion de Popelis.""" import json import urllib.error import urllib.request def popelis_create_user( base_url: str, admin_token: str, username: str, password: str, timeout: float = 30.0, ) -> dict: """Crea un usuario en Popelis via la API de administracion. Hace POST a {base_url}/api/admin/users con el token de admin y las credenciales del nuevo usuario. El backend crea ademas automaticamente un usuario Jellyfin espejo (Modelo B). Args: base_url: URL base del servicio, sin trailing slash. Ej: "https://popelis.datardos.com" admin_token: Token de administracion (cabecera X-Admin-Token). Mantenerlo en secreto — no logear. username: Nombre de usuario a crear. Debe ser unico. password: Contrasena inicial del usuario. timeout: Timeout en segundos para la peticion HTTP. Default 30.0. Returns: Dict con los datos del usuario creado: {"id": N, "username": "...", "jfUserId": "..."} Raises: ValueError: Si el servidor devuelve 4xx o 5xx. El mensaje incluye el status code y el campo "error" del body JSON si existe. urllib.error.URLError: Si no se puede conectar al servidor. """ url = f"{base_url.rstrip('/')}/api/admin/users" payload = json.dumps({"username": username, "password": password}).encode("utf-8") req = urllib.request.Request( url, data=payload, headers={ "Content-Type": "application/json", "X-Admin-Token": admin_token, }, method="POST", ) try: with urllib.request.urlopen(req, timeout=timeout) as resp: body = resp.read() return json.loads(body) except urllib.error.HTTPError as exc: raw = exc.read() try: detail = json.loads(raw).get("error", raw.decode("utf-8", errors="replace")) except Exception: detail = raw.decode("utf-8", errors="replace") raise ValueError( f"popelis_create_user: HTTP {exc.code} — {detail}" ) from exc