--- name: popelis_create_user kind: function lang: py domain: infra version: "1.0.0" purity: impure signature: "def popelis_create_user(base_url: str, admin_token: str, username: str, password: str, timeout: float = 30.0) -> dict" description: "Crea un usuario en la API de administracion de Popelis (POST /api/admin/users). El backend crea automaticamente un usuario Jellyfin espejo (Modelo B). Registro CERRADO: requiere cabecera X-Admin-Token." tags: [popelis, http, admin, user, jellyfin, infra] params: - name: base_url desc: "URL base del servicio sin trailing slash. Ej: https://popelis.datardos.com" - name: admin_token desc: "Token de administracion. Se envia como cabecera X-Admin-Token. No logear ni exponer." - name: username desc: "Nombre de usuario a crear. Debe ser unico en el sistema." - name: password desc: "Contrasena inicial del nuevo usuario." - name: timeout desc: "Timeout en segundos para la peticion HTTP. Default 30.0." output: "Dict con los datos del usuario creado: {id: N, username: str, jfUserId: str}" uses_functions: [] uses_types: [] returns: [] returns_optional: false error_type: "error_go_core" imports: ["json", "urllib.request", "urllib.error"] tested: false tests: [] test_file_path: "" file_path: "python/functions/infra/popelis_create_user.py" --- ## Ejemplo ```python from infra.popelis_create_user import popelis_create_user result = popelis_create_user( base_url="https://popelis.datardos.com", admin_token="", username="alice", password="s3cur3pass", ) # result == {"id": 42, "username": "alice", "jfUserId": "abc123-..."} print(result) ``` ## Cuando usarla Cuando necesites dar de alta un usuario nuevo en Popelis desde un script de administracion, pipeline de onboarding o agente. Usar ANTES de `popelis_set_password` (que requiere que el usuario ya exista). ## Gotchas - **Token sensible**: `admin_token` es un secreto. Nunca logear el valor, interpolarlo en URLs ni persistirlo en texto plano. - **Registro cerrado**: el endpoint rechaza cualquier peticion sin `X-Admin-Token` valido (HTTP 401/403). - **409 si ya existe**: si el `username` ya esta registrado, el servidor devuelve HTTP 409 y la funcion lanza `ValueError`. Para idempotencia, captura el error y comprueba `"409"` en el mensaje o verifica existencia previa. - **Jellyfin espejo**: el backend crea automaticamente un usuario Jellyfin con el mismo `username`. Si Jellyfin no esta disponible en el momento de la llamada, la creacion puede fallar en el backend (el error llega como 5xx). - **Solo stdlib**: no requiere `requests` ni dependencias externas — usa `urllib.request`.