""" Операция: получить параметры операции с ТЕКУЩИМИ значениями инстанса. Источник правды — Nubes API: 1. GET /instances/{instanceUid} → state.params (текущие значения, ключ = код параметра) 2. GET /instanceOperations/default/{opId} (шаблон: код, тип, valueList, dataDescriptor) 3. Смержить: defaultValue = state.params["код"] ?? template.defaultValue """ def get_params_with_current_values(client, op_id, instance_uid): """ Возвращает список параметров (dict) для заполнения формы операции. Каждый элемент: svcOperationCfsParamId — числовой ID параметра name — код параметра (напр. "durationMs") dataType — тип (напр. "integer >= 0", "boolean", "string") isRequired — обязательный? defaultValue — ТЕКУЩЕЕ значение из state.params или шаблонный default valueList — список допустимых значений (если есть) dataDescriptor — вложенная структура для map-параметров (если есть) """ # --- Шаг 1: текущие значения из инстанса --- inst_data = client.get(f"/instances/{instance_uid}") state_params = inst_data.get("instance", {}).get("state", {}).get("params", {}) or {} # state_params — dict вида {"whereFail": "1", "durationMs": "0", "bodymessage": "mess", ...} # --- Шаг 2: шаблон параметров операции --- tmpl_data = client.get(f"/instanceOperations/default/{op_id}") tmpl_params = tmpl_data.get("svcOperation", {}).get("cfsParams", []) or [] # --- Шаг 3: слияние --- result = [] for p in tmpl_params: pid = p["svcOperationCfsParamId"] # числовой ID (напр. 198) code = p.get("svcOperationCfsParam", "") # код/имя (напр. "durationMs") data_type = p.get("dataType", "") required = p.get("isRequired", False) tmpl_default = p.get("defaultValue") # шаблонный default value_list = p.get("valueList") dd = p.get("dataDescriptor") # вложенная структура (map-параметры) # Берём текущее значение из state.params по коду, # если нет — используем шаблонный defaultValue. current = state_params.get(code) if current is not None: # Приводим к строке — фронт ожидает строки в полях ввода. # bool → "true"/"false", dict → JSON, остальное → str() if isinstance(current, bool): current = "true" if current else "false" elif isinstance(current, dict): import json current = json.dumps(current) else: current = str(current) merged_value = current else: merged_value = tmpl_default result.append({ "svcOperationCfsParamId": pid, "name": code, "dataType": data_type, "isRequired": required, "defaultValue": merged_value, "valueList": value_list, "refSvcId": p.get("refSvcId"), # если параметр ссылается на другой сервис "dataDescriptor": ( { k: { "dataType": v.get("dataType", ""), "valueList": _normalize_value_list(v.get("valueList", "")), "defaultValue": v.get("defaultValue", ""), "isRequired": v.get("isRequired", False), } for k, v in dd.items() } if isinstance(dd, dict) else None ), }) return result def _normalize_value_list(vl): """Nubes API возвращает valueList как CSV-строку или массив. Приводим к list для фронтенда.""" if vl is None: return None if isinstance(vl, list): return vl if isinstance(vl, str): return [x.strip() for x in vl.split(',') if x.strip()] or None return None