/
Chaizee
/
ZenithCode_Incident-LLM-analytics
Обзор
Документация
Войти
/
Chaizee
/
ZenithCode_Incident-LLM-analytics
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
ui
src/report.py
92 строки
3 KB
Chaizee
feat: add llm-analyzer realisation
08 июн 2026, 18:44
08 июн 2026, 18:44
0796e1d
Код
Авторство
О чём код?
from __future__ import annotations from io import BytesIO from pathlib import Path import pandas as pd from loguru import logger from openpyxl.styles import Alignment, Font, PatternFill from openpyxl.utils import get_column_letter _HEADER = PatternFill("solid", fgColor="1F4E79") _FONT = Font(color="FFFFFF", bold=True) _WRAP = Alignment(wrap_text=True, vertical="top") def _to_report_df(rankings: pd.DataFrame) -> pd.DataFrame: if rankings.empty: return pd.DataFrame({"Сообщение": ["Проблем не найдено"]}) rows = [] for _, r in rankings.iterrows(): examples = r.get("example_texts") or [] issues = r.get("top_core_issues") or [] rows.append( { "Ранг": r.get("rank"), "Муниципалитет": r.get("municipality"), "Населённый пункт": r.get("settlement"), "Кол-во проблем": r.get("problem_count"), "Средняя тяжесть": round(float(r.get("mean_severity", 0)), 2), "ТОП сути": ", ".join(issues) if isinstance(issues, list) else str(issues), "Почему в топе": r.get("example_reason", ""), "Примеры обращений": "\n---\n".join(map(str, examples)), } ) return pd.DataFrame(rows) def _style_sheet(ws) -> None: for cell in ws[1]: cell.fill = _HEADER cell.font = _FONT for row in ws.iter_rows(min_row=2): for cell in row: cell.alignment = _WRAP for col in ws.columns: letter = get_column_letter(col[0].column) ws.column_dimensions[letter].width = min( max(len(str(c.value or "")) for c in col) + 2, 55 ) def _to_critical_df(critical: pd.DataFrame) -> pd.DataFrame: if critical.empty: return pd.DataFrame({"Сообщение": ["Обращений с тяжестью 5 не найдено"]}) return critical.rename( columns={ "incident_id": "Номер инцидента", "municipality": "Муниципалитет", "settlement": "Населённый пункт", "core_issue": "Суть проблемы", "incident_text": "Текст обращения", } ) def build_excel(top10: pd.DataFrame, top3: pd.DataFrame, critical: pd.DataFrame | None = None) -> bytes: buffer = BytesIO() try: with pd.ExcelWriter(buffer, engine="openpyxl") as writer: _to_report_df(top10).to_excel(writer, sheet_name="ТОП-10", index=False) _to_report_df(top3).to_excel(writer, sheet_name="ТОП-3", index=False) _to_critical_df(critical if critical is not None else pd.DataFrame()).to_excel( writer, sheet_name="Тяжесть 5", index=False ) for name in writer.sheets: _style_sheet(writer.sheets[name]) except Exception as exc: logger.error("build_excel: {}", exc) raise return buffer.getvalue() def save_excel( top10: pd.DataFrame, top3: pd.DataFrame, path: Path, critical: pd.DataFrame | None = None, ) -> Path: path.parent.mkdir(parents=True, exist_ok=True) path.write_bytes(build_excel(top10, top3, critical)) return path