Files
DumiFlex-ComfyUI-Wildcard-P…/wp_api/cascade.py
T

88 lines
3.0 KiB
Python

"""HTTP routes for cascade-edit mutations.
POST /wp/api/cascade/apply → engine.cascade.orchestrator.apply_cascade
POST /wp/api/cascade/undo → engine.cascade.undo.undo_cascade
"""
from __future__ import annotations
from aiohttp import web
from engine.cascade.orchestrator import apply_cascade as _apply
from engine.cascade.undo import undo_cascade as _undo
from wp_api._helpers import db_session, json_error, json_ok
async def cascade_apply(request: web.Request) -> web.Response:
"""POST /wp/api/cascade/apply — apply cascade-edit mutations.
Body shape::
{
"kind": str, # "wildcard", "category", etc.
"id": str, # target entity UUID
"action": str, # "delete", "rename", etc.
"dry_run": bool, # optional, default False
"cascade_refs": bool, # optional, default True
"new_name": str, # optional, for rename actions
"extra": dict, # optional, for subcategory/combine_var ops
}
On success: ``{"ok": True, "undo_entry_id": str, "affected_count": int, "diff": list}``
(dry_run mode returns ``affected_count`` and ``affected_entities`` instead of ``diff``).
On error: ``{"error": str}`` with status 400.
"""
try:
body = await request.json()
except Exception:
return json_error("invalid JSON body", status=400)
if not isinstance(body, dict):
return json_error("body must be a JSON object", status=400)
with db_session(request) as conn:
result = _apply(conn, body)
if not result.get("ok"):
return json_error(result.get("error", "apply failed"), status=400)
return json_ok(result)
async def cascade_undo(request: web.Request) -> web.Response:
"""POST /wp/api/cascade/undo — reverse a previous cascade-edit apply.
Body shape::
{"undo_entry_id": str}
On success: ``{"ok": True}`` (200).
Missing or non-string ``undo_entry_id`` → 400.
Unknown ``undo_entry_id`` → **404** (engine returns "not found" in error).
Other failures → 400.
"""
try:
body = await request.json()
except Exception:
return json_error("invalid JSON body", status=400)
if not isinstance(body, dict):
return json_error("body must be a JSON object", status=400)
undo_id = body.get("undo_entry_id")
if not isinstance(undo_id, str) or not undo_id:
return json_error("undo_entry_id required", status=400)
with db_session(request) as conn:
result = _undo(conn, undo_id)
if not result.get("ok"):
error = result.get("error", "undo failed")
# Engine returns "undo entry not found" for missing entries;
# map to 404 for clean distinction from other errors.
status = 404 if "not found" in error.lower() else 400
return json_error(error, status=status)
return json_ok(result)
def register(router) -> None:
"""Register cascade routes on the given aiohttp router."""
router.add_post("/wp/api/cascade/apply", cascade_apply)
router.add_post("/wp/api/cascade/undo", cascade_undo)