From 304c4703b90664247c0b2a2cd2c3e8287c04019c Mon Sep 17 00:00:00 2001 From: "alexei.dolgolyov" Date: Tue, 10 Mar 2026 14:27:44 +0300 Subject: [PATCH] Add manual backup trigger endpoint POST /api/v1/system/auto-backup/trigger creates a backup on demand and returns the created file info (filename, size, timestamp). Co-Authored-By: Claude Opus 4.6 --- TODO.md | 2 +- server/src/wled_controller/api/routes/system.py | 10 ++++++++++ server/src/wled_controller/core/backup/auto_backup.py | 8 ++++++++ 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/TODO.md b/TODO.md index c1bff0d..9d53a8c 100644 --- a/TODO.md +++ b/TODO.md @@ -41,7 +41,7 @@ Priority: `P1` quick win · `P2` moderate · `P3` large effort ## Code Health - [ ] `P1` **"Start All" targets button** — "Stop All" exists but "Start All" is missing -- [ ] `P2` **Manual backup trigger endpoint** — `POST /system/auto-backup/trigger` (~5 lines) +- [x] `P2` **Manual backup trigger endpoint** — `POST /system/auto-backup/trigger` (~5 lines) - [ ] `P2` **Scene snapshot should capture device brightness** — `software_brightness` not saved/restored - [ ] `P2` **Distinguish "crashed" vs "stopped" in dashboard** — `metrics.last_error` is already populated - [ ] `P3` **Home Assistant MQTT discovery** — publish auto-discovery payloads; MQTT infra already exists diff --git a/server/src/wled_controller/api/routes/system.py b/server/src/wled_controller/api/routes/system.py index 4e9c963..c0afca7 100644 --- a/server/src/wled_controller/api/routes/system.py +++ b/server/src/wled_controller/api/routes/system.py @@ -489,6 +489,16 @@ async def update_auto_backup_settings( ) +@router.post("/api/v1/system/auto-backup/trigger", tags=["System"]) +async def trigger_backup( + _: AuthRequired, + engine: AutoBackupEngine = Depends(get_auto_backup_engine), +): + """Manually trigger a backup now.""" + backup = await engine.trigger_backup() + return {"status": "ok", "backup": backup} + + @router.get( "/api/v1/system/backups", response_model=BackupListResponse, diff --git a/server/src/wled_controller/core/backup/auto_backup.py b/server/src/wled_controller/core/backup/auto_backup.py index 3539814..9f8e372 100644 --- a/server/src/wled_controller/core/backup/auto_backup.py +++ b/server/src/wled_controller/core/backup/auto_backup.py @@ -211,6 +211,14 @@ class AutoBackupEngine: raise ValueError("Invalid filename") return target + async def trigger_backup(self) -> dict: + """Manually trigger a backup and prune old ones. Returns the created backup info.""" + await self._perform_backup() + self._prune_old_backups() + # Return the most recent backup entry + backups = self.list_backups() + return backups[0] if backups else {} + def delete_backup(self, filename: str) -> None: target = self._safe_backup_path(filename) if not target.exists():