ChartPipeline / app.py
Ray1ee01's picture
Add runnable ChartPipeline Space
216c0a4 verified
Raw
History Blame Contribute Delete
3.16 kB
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"<pre>Invalid JSON: {exc}</pre>", 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 "<pre>Chart generation failed. Check the input schema and chart template.</pre>", 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")),
)