ayushbharadva/patchpilot-api
0
1#!/usr/bin/env python32"""Restore demo memory on Render when the ephemeral disk is empty.3 4Called from scripts/render_start.sh before uvicorn starts. If5.patchpilot_memory/ already has data (persistent disk or prior boot),6this is a no-op. Otherwise downloads SNAPSHOT_URL (if set) or restores7patchpilot_memory.snapshot.tar from the repo root when present.8"""9 10from __future__ import annotations11 12import os13import sys14import urllib.request15from pathlib import Path16 17REPO_ROOT = Path(__file__).resolve().parent.parent18if str(REPO_ROOT) not in sys.path:19 sys.path.insert(0, str(REPO_ROOT))20 21from scripts.snapshot_memory import SNAPSHOT_PATH, restore # noqa: E40222 23MEMORY_ROOT = Path(24 os.environ.get("SYSTEM_ROOT_DIRECTORY", str(REPO_ROOT / ".patchpilot_memory")),25)26 27# Canonical public demo snapshot (GitHub release asset). Render dashboard env28# vars are NOT synced from render.yaml — the same failure class that kept the29# stale CORS_ORIGINS live — so SNAPSHOT_URL may be unset/stale in prod. With30# this fallback baked in, every boot on a fresh ephemeral disk (deploys AND31# crash-restarts) self-heals back to the seeded demo memory.32DEFAULT_SNAPSHOT_URL = (33 "https://github.com/ayushbharadva/patch-pilot/releases/download/"34 "memory-snapshot-v1/patchpilot_memory.snapshot.tar"35)36 37 38def memory_is_populated() -> bool:39 return MEMORY_ROOT.exists() and any(MEMORY_ROOT.iterdir())40 41 42def download_snapshot(url: str) -> None:43 print(f"Downloading memory snapshot from {url} ...")44 urllib.request.urlretrieve(url, SNAPSHOT_PATH) # noqa: S31045 print(f"Saved snapshot to {SNAPSHOT_PATH}")46 47 48def main() -> int:49 if memory_is_populated():50 print(f"Memory already present at {MEMORY_ROOT} — skipping restore.")51 return 052 53 snapshot_url = os.environ.get("SNAPSHOT_URL", "").strip() or DEFAULT_SNAPSHOT_URL54 if snapshot_url and not SNAPSHOT_PATH.exists():55 try:56 download_snapshot(snapshot_url)57 except Exception as exc: # noqa: BLE00158 print(f"WARNING: snapshot download failed: {exc}")59 60 if not SNAPSHOT_PATH.exists():61 print(62 "WARNING: no snapshot available — API will start with empty memory. "63 "Set SNAPSHOT_URL to a GitHub release asset or run seed after deploy."64 )65 return 066 67 try:68 restore()69 except FileNotFoundError as exc:70 print(f"WARNING: snapshot restore failed: {exc}")71 return 072 73 print(f"Restored demo memory to {MEMORY_ROOT}")74 return 075 76 77if __name__ == "__main__":78 raise SystemExit(main())79 