from __future__ import annotations import json import os import tempfile from pathlib import Path import gradio as gr from modules.chart_engine.chart_engine import process from modules.chart_engine.template.template_registry import scan_templates, templates ROOT = Path(__file__).resolve().parent SAMPLE_PATH = ROOT / "examples" / "chart_engine_sample.json" def _load_sample() -> str: return SAMPLE_PATH.read_text(encoding="utf-8") def _available_chart_names() -> list[str]: scan_templates() names: list[str] = [] for by_type in templates.values(): for by_name in by_type.values(): names.extend(by_name.keys()) return sorted(set(names)) def render_chart(json_text: str, chart_name: str) -> tuple[str, str | None]: try: payload = json.loads(json_text) except json.JSONDecodeError as exc: return f"
Invalid JSON: {exc}
", None with tempfile.TemporaryDirectory(prefix="chartpipeline_space_") as tmp_dir: tmp_path = Path(tmp_dir) input_path = tmp_path / "input.json" output_path = tmp_path / "chart.svg" input_path.write_text(json.dumps(payload, ensure_ascii=False), encoding="utf-8") ok = process( input=str(input_path), output=str(output_path), chart_name=chart_name, ) if not ok or not output_path.exists(): return "
Chart generation failed. Check the input schema and chart template.
", None svg = output_path.read_text(encoding="utf-8") persistent_output = Path(tempfile.gettempdir()) / "chartpipeline_space_latest.svg" persistent_output.write_text(svg, encoding="utf-8") return svg, str(persistent_output) chart_names = _available_chart_names() default_chart = "donut_plain_chart_01" if default_chart not in chart_names and chart_names: default_chart = chart_names[0] with gr.Blocks(title="ChartPipeline") as demo: gr.Markdown("# ChartPipeline") gr.Markdown("Generate SVG charts from ChartPipeline JSON using the bundled chart engine templates.") with gr.Row(): with gr.Column(scale=1): chart_name = gr.Dropdown( choices=chart_names, value=default_chart, label="Chart template", allow_custom_value=True, ) json_input = gr.Code( value=_load_sample(), language="json", label="Input JSON", lines=28, ) render_button = gr.Button("Render SVG", variant="primary") with gr.Column(scale=1): svg_output = gr.HTML(label="SVG preview") file_output = gr.File(label="Download SVG") render_button.click( render_chart, inputs=[json_input, chart_name], outputs=[svg_output, file_output], ) demo.load( render_chart, inputs=[json_input, chart_name], outputs=[svg_output, file_output], ) if __name__ == "__main__": demo.launch( server_name="0.0.0.0", server_port=int(os.environ.get("PORT", "7860")), )