Initial Animatrix import
This commit is contained in:
64
backend/app/services/workflow_binder.py
Normal file
64
backend/app/services/workflow_binder.py
Normal file
@@ -0,0 +1,64 @@
|
||||
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
|
||||
Reference in New Issue
Block a user