Files
Project_Animatix/backend/app/services/workflow_binder.py
2026-04-17 19:11:57 +05:30

65 lines
2.2 KiB
Python

import copy
import json
import logging
from pathlib import Path
from typing import Any, Dict, Optional
logger = logging.getLogger(__name__)
WORKFLOWS_ROOT = Path(__file__).parents[3] / "workflows"
_REGISTRY: Dict[str, Path] = {}
def _discover() -> None:
_REGISTRY.clear()
for path in WORKFLOWS_ROOT.rglob("*.json"):
try:
with open(path, encoding="utf-8") as handle:
data = json.load(handle)
meta = data.get("__animatrix_meta__", {})
_REGISTRY[meta.get("name") or path.stem] = path
except Exception as exc:
logger.warning("Could not load workflow %s: %s", path, exc)
_discover()
def select_template_name(mode: str, submode: Optional[str]) -> str:
if mode == "animate":
return f"wan22_animate_{submode or 'move'}"
if mode == "audio":
return "wan22_s2v"
raise ValueError(f"Unknown mode: {mode}")
class WorkflowBinder:
def __init__(self, template_name: str):
if template_name not in _REGISTRY:
_discover()
if template_name not in _REGISTRY:
raise FileNotFoundError(
f"Workflow template '{template_name}' not found in {WORKFLOWS_ROOT}. Available: {list(_REGISTRY.keys())}"
)
with open(_REGISTRY[template_name], encoding="utf-8") as handle:
self._raw = json.load(handle)
self._meta = self._raw.get("__animatrix_meta__", {})
self._param_nodes = self._meta.get("param_nodes", {})
self.version = self._meta.get("version", "unknown")
self.status = self._meta.get("status", "")
def bind(self, params: Dict[str, Any]) -> Dict[str, Any]:
workflow = copy.deepcopy(self._raw)
workflow.pop("__animatrix_meta__", None)
for param_key, value in params.items():
if value is None:
continue
node_spec = self._param_nodes.get(param_key)
if not node_spec:
continue
node_id = str(node_spec["node_id"])
input_name = node_spec["input"]
if node_id in workflow:
workflow[node_id]["inputs"][input_name] = value
return workflow