From 0520a1117c345a8151fc0c1f898d10ed4946cf4d Mon Sep 17 00:00:00 2001 From: SERTY Date: Mon, 21 Jul 2025 20:50:35 +0300 Subject: [PATCH] dry run added --- config.py | 11 ++++++++++- sd_api.py | 41 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 1 deletion(-) diff --git a/config.py b/config.py index 2ee6b44..e6a533c 100644 --- a/config.py +++ b/config.py @@ -31,4 +31,13 @@ FIND_WORKSTATIONS_URL = f"{SD_BASE_URL}/find/objectBase$Workstation" # URL для создания будет формироваться динамически, но базовый шаблон такой: CREATE_FR_URL = f"{SD_BASE_URL}/create-m2m/objectBase$FR" # URL для редактирования будет принимать UUID объекта -EDIT_FR_URL_TEMPLATE = f"{SD_BASE_URL}/edit/{{uuid}}" \ No newline at end of file +EDIT_FR_URL_TEMPLATE = f"{SD_BASE_URL}/edit/{{uuid}}" + +# --- Testing Configuration --- +# Установите в "True" для режима "сухого запуска" (dry run). +# В этом режиме запросы на изменение/создание не будут отправляться в SD, +# а будут сохраняться в локальные файлы для анализа. +DRY_RUN = os.getenv('DRY_RUN', 'True').lower() in ('true', '1', 't') + +# Путь для сохранения тестовых выходных данных +TEST_OUTPUT_PATH = os.path.join(os.path.dirname(__file__), 'test_output') \ No newline at end of file diff --git a/sd_api.py b/sd_api.py index d29e289..1d02cd1 100644 --- a/sd_api.py +++ b/sd_api.py @@ -3,7 +3,9 @@ import requests import logging import json +import os from typing import List, Dict, Any +from datetime import datetime # Импортируем нашу конфигурацию import config @@ -56,6 +58,12 @@ class ServiceDeskClient: error_message = f"Request failed for URL {url}: {e}" log.error(error_message) raise ServiceDeskAPIError(error_message) from e + + def _ensure_test_output_dir(self): + """Проверяет и создает директорию для тестовых файлов.""" + if not os.path.exists(config.TEST_OUTPUT_PATH): + os.makedirs(config.TEST_OUTPUT_PATH) + log.info(f"Создана директория для тестовых данных: {config.TEST_OUTPUT_PATH}") def get_all_frs(self) -> List[Dict]: """Получает список всех фискальных регистраторов.""" @@ -94,10 +102,28 @@ class ServiceDeskClient: def update_fr(self, uuid: str, data: Dict) -> None: """ Обновляет существующий фискальный регистратор. + В режиме DRY_RUN сохраняет данные в файл. :param uuid: UUID объекта для редактирования. :param data: Словарь с полями для обновления. """ + if config.DRY_RUN: + self._ensure_test_output_dir() + filename = f"update_{uuid}_{datetime.now().strftime('%Y%m%d_%H%M%S')}.json" + filepath = os.path.join(config.TEST_OUTPUT_PATH, filename) + + # Сохраняем и URL, и параметры для полного понимания + output_data = { + "action": "UPDATE", + "target_uuid": uuid, + "payload": data + } + + with open(filepath, 'w', encoding='utf-8') as f: + json.dump(output_data, f, indent=4, ensure_ascii=False) + log.warning(f"[DRY RUN] Пропущено обновление {uuid}. Данные сохранены в {filepath}") + return + log.info(f"Обновление объекта ФР с UUID: {uuid}...") # Примечание: старый код использовал POST с параметрами для редактирования. # Если API требует form-encoded data, а не JSON, нужно использовать `data=data` вместо `json=data`. @@ -109,10 +135,25 @@ class ServiceDeskClient: def create_fr(self, data: Dict) -> Dict: """ Создает новый фискальный регистратор. + В режиме DRY_RUN сохраняет тело запроса в файл. :param data: Словарь с данными для создания объекта (тело запроса). :return: JSON-ответ от сервера, содержащий UUID нового объекта. """ + serial_number = data.get('FRSerialNumber', 'unknown_sn') + if config.DRY_RUN: + self._ensure_test_output_dir() + filename = f"create_{serial_number}_{datetime.now().strftime('%Y%m%d_%H%M%S')}.json" + filepath = os.path.join(config.TEST_OUTPUT_PATH, filename) + + # Сохраняем только тело запроса + with open(filepath, 'w', encoding='utf-8') as f: + json.dump(data, f, indent=4, ensure_ascii=False) + log.warning(f"[DRY RUN] Пропущено создание ФР с S/N {serial_number}. Body запроса сохранено в {filepath}") + + # В режиме dry run возвращаем фейковый ответ, чтобы не сломать вызывающий код + return {"action": "DRY_RUN_CREATE", "saved_to": filepath} + log.info(f"Создание нового ФР с серийным номером: {data.get('FRSerialNumber')}...") # Параметр для получения UUID в ответе params = {'attrs': 'UUID'}