#!/usr/bin/env python3 # -*- coding: utf-8 -*- """同步配置到 207 并部署 LiteLLM(pip + systemd)。""" from __future__ import annotations import sys from pathlib import Path import _bootstrap # noqa: F401 import _config as LC from dify_api import Dify import _config as C # noqa: E402 ROOT = Path(__file__).resolve().parents[2] LOCAL_PATCH = ROOT / "patches_cursor" / "LiteLLM部署" LOCAL_SH = ROOT / "scripts_bash_cursor" / "LiteLLM部署" / "LiteLLM_01_部署.sh" REMOTE_PATCH = LC.LITELLM_PATCH_DIR def sync_dir(d: Dify, local: Path, remote: str) -> None: d.sh(f"mkdir -p '{remote}'") for fp in local.rglob("*"): if not fp.is_file(): continue if fp.name.startswith(".") and fp.name != ".env": continue rel = fp.relative_to(local).as_posix() rpath = f"{remote}/{rel}" parent = "/".join(rpath.split("/")[:-1]) d.sh(f"mkdir -p '{parent}'") d.sftp.put(str(fp), rpath) print(f" put {rel}") def main() -> int: d = Dify(C.DIFY_EMAIL, C.DIFY_PASSWORD) try: try: d.login() except Exception as e: # noqa: BLE001 print("[WARN] Dify login 跳过:", e) print("[INFO] sync patch →", REMOTE_PATCH) sync_dir(d, LOCAL_PATCH, REMOTE_PATCH) d.sftp.put(str(LOCAL_SH), "/tmp/LiteLLM_01_部署.sh") d.sh("chmod +x /tmp/LiteLLM_01_部署.sh") out, err = d.sh("bash /tmp/LiteLLM_01_部署.sh") print(out or err) raw, _ = d.sh(f"curl -sf '{LC.LITELLM_BASE}/health/liveliness'; echo; echo EXIT:$?") print("[DEBUG] liveliness:", raw) if "EXIT:0" not in (raw or "") and "alive" not in (raw or "").lower(): print("[FAIL] LiteLLM 未就绪") return 1 print("[OK] LiteLLM", LC.LITELLM_BASE) return 0 finally: d.close() if __name__ == "__main__": sys.exit(main())