SFM/run_local.py
2026-09-17 13:04:35 +03:00

110 lines
4.0 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""Локальный прогон пайплайна без SMB и без Streamlit UI.
Берёт XML-файлы из указанной локальной папки, парсит их и формирует
report.xlsx + protocol.xlsx в текущей рабочей директории (или в папке,
заданной через --out).
Пример:
python scripts/run_local.py /path/to/xml_folder
python scripts/run_local.py /path/to/xml_folder --out /tmp/result
"""
from __future__ import annotations
import argparse
import getpass
import sys
from datetime import datetime
from pathlib import Path
ROOT = Path(__file__).resolve().parent
if str(ROOT) not in sys.path:
sys.path.insert(0, str(ROOT))
from app.pipeline.parser import parse_xml_content # noqa: E402
from app.pipeline.protocol import ProtocolRow, write_protocol # noqa: E402
from app.pipeline.report import ReportRow, StreamingReportWriter # noqa: E402
from app.pipeline.service import ( # noqa: E402 # переиспользуем логику статуса
_resolve_parse_status,
)
def main() -> int:
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("input_dir", type=Path, help="Локальная папка с XML-файлами")
parser.add_argument(
"--out",
type=Path,
default=Path.cwd(),
help="Куда сохранить report.xlsx/protocol.xlsx (по умолчанию — текущая директория)",
)
parser.add_argument(
"--launcher",
default=getpass.getuser(),
help="Имя запустившего (для протокола); по умолчанию — текущий пользователь ОС",
)
args = parser.parse_args()
input_dir: Path = args.input_dir
out_dir: Path = args.out
if not input_dir.is_dir():
print(f"Папка не найдена: {input_dir}", file=sys.stderr)
return 1
out_dir.mkdir(parents=True, exist_ok=True)
xml_paths = sorted(input_dir.rglob("*.xml"))
if not xml_paths:
print(f"В {input_dir} не найдено XML-файлов.")
return 1
report_writer = StreamingReportWriter()
protocol_rows: list[ProtocolRow] = []
for xml_path in xml_paths:
file_name = xml_path.name
content = xml_path.read_bytes()
parse_result = parse_xml_content(file_name=file_name, xml_content=content)
for row in parse_result.rows:
report_writer.append_row(
ReportRow(
file_name=row.file_name,
record_id=row.record_id,
operation_index=row.operation_index,
operation_fields=row.operation_fields,
participant_fields=row.participant_fields,
is_continuation=row.is_continuation,
)
)
status, message = _resolve_parse_status(parse_result)
protocol_rows.append(
ProtocolRow(
file_name=file_name,
status=status,
message=message,
operations_total=parse_result.total_operations,
rows_written=len(parse_result.rows),
launcher=args.launcher,
processed_at=datetime.now(),
)
)
print(f"{file_name}: {status} — {message}")
report_path = out_dir / "report.xlsx"
protocol_path = out_dir / "protocol.xlsx"
report_writer.save(report_path)
write_protocol(protocol_rows, protocol_path)
processed = sum(1 for r in protocol_rows if r.status == "success")
partial = sum(1 for r in protocol_rows if r.status == "partial")
errors = sum(1 for r in protocol_rows if r.status == "error")
print(f"\nГотово: успешно={processed}, частично={partial}, с ошибками={errors}.")
print(f"Отчёт: {report_path}")
print(f"Протокол: {protocol_path}")
return 0
if __name__ == "__main__":
raise SystemExit(main())