Blender / app.py
Percy3822's picture
Update app.py
5673183 verified
import gradio as gr
import tempfile, os, subprocess, json
BLENDER = "blender" # symlinked in Dockerfile
def build_prop(spec_file):
# Load and sanity-check JSON
try:
spec_path = spec_file.name
with open(spec_path, "r") as f:
spec = json.load(f)
except Exception as e:
return None, f"Invalid JSON: {e}"
# Minimal schema checks
ptype = spec.get("type")
if not ptype:
return None, "Spec must include a 'type' field (e.g., 'book')."
if "name" not in spec:
spec["name"] = f"{ptype}_auto"
# Route to generator (extend here with more types later)
generator = "generate_book.py" if ptype == "book" else "generate_book.py"
out_dir = tempfile.mkdtemp()
cmd = [BLENDER, "-b", "-P", generator, "--", "--spec", spec_path, "--out", out_dir]
try:
run = subprocess.run(cmd, check=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True)
logs = run.stdout
except subprocess.CalledProcessError as e:
return None, f"Blender failed:\n{e.stdout}"
# Return first .glb produced
glbs = [os.path.join(out_dir, f) for f in os.listdir(out_dir) if f.lower().endswith(".glb")]
if not glbs:
return None, f"No .glb exported.\nLogs:\n{logs}"
return glbs[0], "Success."
demo = gr.Interface(
fn=build_prop,
inputs=gr.File(label="Upload PropSpec JSON"),
outputs=[gr.File(label="Generated .glb"), gr.Textbox(label="Log")],
title="Code‑Generated Props (Blender Headless)",
description="Upload a JSON PropSpec (supports 'book' for now) and download a .glb.",
allow_flagging="never" # prevent write-permission errors on HF Spaces
)
if __name__ == "__main__":
demo.launch(server_name="0.0.0.0", server_port=int(os.getenv("PORT", "7860")))