|
|
|
|
|
import os |
|
|
from typing import Optional, Dict, Any |
|
|
|
|
|
import pandas as pd |
|
|
from jinja2 import Environment, FileSystemLoader |
|
|
|
|
|
from utils.tracing import Tracer |
|
|
from utils.config import AppConfig |
|
|
|
|
|
|
|
|
class ReportTool: |
|
|
def __init__(self, cfg: AppConfig, tracer: Tracer): |
|
|
self.cfg = cfg |
|
|
self.tracer = tracer |
|
|
templates_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "templates")) |
|
|
self.env = Environment(loader=FileSystemLoader(templates_dir), autoescape=False) |
|
|
|
|
|
def render_and_save( |
|
|
self, |
|
|
user_query: str, |
|
|
sql_preview: Optional[pd.DataFrame], |
|
|
predict_preview: Optional[pd.DataFrame], |
|
|
explain_images: Dict[str, str], |
|
|
plan: Dict[str, Any], |
|
|
) -> str: |
|
|
tmpl = self.env.get_template("report_template.md") |
|
|
html_body = tmpl.render( |
|
|
user_query=user_query, |
|
|
plan=plan, |
|
|
sql_preview=sql_preview.to_markdown(index=False) if isinstance(sql_preview, pd.DataFrame) else "", |
|
|
predict_preview=predict_preview.to_markdown(index=False) if isinstance(predict_preview, pd.DataFrame) else "", |
|
|
explain_images=explain_images or {}, |
|
|
) |
|
|
out_name = f"report_{pd.Timestamp.utcnow().strftime('%Y%m%d_%H%M%S')}.html" |
|
|
out_path = os.path.abspath(os.path.join(os.getcwd(), out_name)) |
|
|
css_link = "templates/report_styles.css" |
|
|
html = f'<link rel="stylesheet" href="{css_link}">\n' + html_body |
|
|
with open(out_path, "w", encoding="utf-8") as f: |
|
|
f.write(html) |
|
|
try: |
|
|
self.tracer.trace_event("report", {"path": out_name}) |
|
|
except Exception: |
|
|
pass |
|
|
return out_name |
|
|
|