Spaces:
Sleeping
Sleeping
| import traceback | |
| from fastapi import APIRouter, BackgroundTasks, HTTPException | |
| from fastapi.responses import FileResponse | |
| from app.models.schemas import RenderRequest, RenderAccepted, JobStatus | |
| from app.core.jobs import new_job_id, write_status, read_status | |
| from app.core.renderer import run_render_job | |
| from app.core.logger import job_log | |
| router = APIRouter() | |
| def _run_job_safe(job_id: str, payload: dict): | |
| try: | |
| run_render_job(job_id, payload) | |
| except Exception as e: | |
| job_log(job_id, f"FAILED: {e}\n{traceback.format_exc()}", stage="error") | |
| write_status(job_id, status="failed", error=str(e)) | |
| def render(req: RenderRequest, background_tasks: BackgroundTasks): | |
| job_id = new_job_id() | |
| write_status(job_id, status="queued", progress="job created") | |
| # Async by design (Rule #5): return immediately, render in background. | |
| # This is what makes the API safe to run on an HF Space free tier without | |
| # hitting request timeouts on multi-minute renders. | |
| background_tasks.add_task(_run_job_safe, job_id, req.model_dump()) | |
| return RenderAccepted(job_id=job_id) | |
| def status(job_id: str): | |
| s = read_status(job_id) | |
| if s is None: | |
| raise HTTPException(status_code=404, detail="job_id not found") | |
| return s | |
| def get_output(filename: str): | |
| import os | |
| path = os.path.join("outputs", filename) | |
| if not os.path.exists(path): | |
| raise HTTPException(status_code=404, detail="file not found") | |
| return FileResponse(path) | |
| def list_templates(): | |
| import os | |
| import json | |
| names = [] | |
| for f in os.listdir("templates"): | |
| if f.endswith(".json"): | |
| with open(os.path.join("templates", f)) as fh: | |
| names.append(json.load(fh)) | |
| return names | |