import argparse
import datetime
import logging
import os
import sys
from abs_art_tabular.core.factories import model_factory, attack_factory
from src import dataset_loader
from src.reporting.renderers.console_renderer import ConsoleRenderer
from src.reporting.renderers.html_renderer import HtmlRenderer
from src.reporting.renderers.json_renderer import JSONRenderer
from src.reporting.report_generator import ReportGenerator
from src.cli.cli import CLI
from src.utils import setup_logging, load_config
[документация]
def main():
setup_logging()
logger = logging.getLogger(__name__)
logging.getLogger("art").setLevel(logging.ERROR)
parser = argparse.ArgumentParser(description="ART Project Pipeline")
parser.add_argument('-c', '--config', dest='config_path', required=False,
help='Path to the JSON or YAML configuration file')
args = parser.parse_args()
if args.config_path:
model_cfg, attacks_cfg, dataset_cfg = load_config(args.config_path)
# Загружаем конфиг для получения reports настроек
import json
import yaml
with open(args.config_path, 'r') as f:
if args.config_path.endswith('.yaml') or args.config_path.endswith('.yml'):
full_config = yaml.safe_load(f)
else:
full_config = json.load(f)
reports_config = full_config.get("reports", {})
else:
cfg = CLI().main_menu()
model_cfg = cfg['model']
attacks_cfg = cfg['attacks']
dataset_cfg = cfg['dataset']
reports_config = cfg.get("reports", {})
# Настройка путей для отчетов из конфига
base_dir = reports_config.get("base_dir", "reports/")
subdirs = reports_config.get("subdirs", {"json": "json/", "html": "html/"})
json_dir = os.path.join(base_dir, subdirs.get("json", "json/"))
html_dir = os.path.join(base_dir, subdirs.get("html", "html/"))
try:
dataset = dataset_loader.DataFactory.load_dataset(dataset_cfg)
X = dataset.data
y = dataset.target
except Exception as e:
logger.error(f"Error loading dataset: {e}")
sys.exit(1)
try:
model_type = model_cfg.get("model_type")
art_model = model_factory.ModelFactory.create_model(model_cfg, X, y)
except Exception as e:
logger.error(f"Error creating model: {e}")
sys.exit(1)
all_attack_data = [] # Хранилище для всех атак
for attack_config in attacks_cfg:
try:
attack = attack_factory.AttackFactory.create_attack(art_model, attack_config)
if attack is None:
logger.info("Attack skipped (incompatible with model).")
continue
except Exception as e:
logger.error(f"Error creating attack: {e}")
sys.exit(1)
try:
attack_data = attack.run(X, y)
# Добавляем атаку в общий список
all_attack_data.append(attack_data)
except Exception as e:
logger.error(f"Error during attack execution: {e}")
sys.exit(1)
# try:
# Получаем общую информацию о модели и датасете
model_name = model_cfg.get("type", "unknown")
dataset_name = dataset_cfg.get("path", "unknown").split("/")[-1]
# === Генерация ОДНОГО отчета для всех атак ===
full_report_data = {
"model_type": model_type,
"model_name": model_name,
"dataset_name": dataset_name,
"attacks": all_attack_data,
"timestamp": datetime.datetime.now().isoformat()
}
timestamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
filename = f"attack_report_{timestamp}"
# Создаем директории для отчетов
os.makedirs(json_dir, exist_ok=True)
os.makedirs(html_dir, exist_ok=True)
# Для YOLO создаем подкаталог в обеих директориях
if model_type == "yolo":
yolo_subdir = f"attack_report_{timestamp}"
current_json_dir = os.path.join(json_dir, yolo_subdir)
current_html_dir = os.path.join(html_dir, yolo_subdir)
os.makedirs(current_json_dir, exist_ok=True)
os.makedirs(current_html_dir, exist_ok=True)
else:
current_json_dir = json_dir
current_html_dir = html_dir
report = ReportGenerator().generate(full_report_data, report_save_path=current_json_dir)
json_output = JSONRenderer().render(report)
# Вывод отчета в консоль
print(ConsoleRenderer().render(report))
# Сохранение отчета в json
filepath = os.path.join(current_json_dir, f"{filename}.json")
with open(filepath, "w") as f:
f.write(json_output)
logger.info(f"Full report saved to {filepath}")
# Сохранение отчета в html
HtmlRenderer().render_to_file(report=report,
filename=f"{filename}.html",
output_dir=current_html_dir)
if __name__ == "__main__":
main()