# space/tools/report_tool.py 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 # Resolve the /space/templates directory reliably whether run as script or module templates_dir = os.path.abspath( os.path.join(os.path.dirname(__file__), "..", "templates") ) self.env = Environment(loader=FileSystemLoader(templates_dir), autoescape=False) self.templates_dir = templates_dir # keep for any future file refs 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: """ Render a simple HTML report from the Markdown-like template, then save it next to app.py. Returns the relative path to the generated HTML file. """ 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 {}, ) # Name the output in the working dir (HF Spaces serves from cwd) 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)) # Link stylesheet relative to the app working dir (matches scaffold layout) css_link = "templates/report_styles.css" html = f'\n' + html_body with open(out_path, "w", encoding="utf-8") as f: f.write(html) # trace try: self.tracer.trace_event("report", {"path": out_name}) except Exception: pass # Return a relative path so Gradio can offer it as a download if needed return out_name