122 lines
3.9 KiB
Python
122 lines
3.9 KiB
Python
"""Flamenco Manager REST API client.
|
|
|
|
Uses httpx (sync) for compatibility with Celery tasks and FastAPI endpoints.
|
|
"""
|
|
import logging
|
|
from typing import Any
|
|
|
|
import httpx
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
DEFAULT_TIMEOUT = 10.0
|
|
|
|
|
|
class FlamencoClient:
|
|
"""Thin wrapper around the Flamenco Manager v3 REST API."""
|
|
|
|
def __init__(self, manager_url: str):
|
|
self.base_url = manager_url.rstrip("/")
|
|
|
|
def _url(self, path: str) -> str:
|
|
return f"{self.base_url}{path}"
|
|
|
|
# ── Job management ──────────────────────────────────────────────────────
|
|
|
|
def submit_job(
|
|
self,
|
|
name: str,
|
|
job_type: str,
|
|
settings: dict[str, Any],
|
|
metadata: dict[str, str] | None = None,
|
|
priority: int = 50,
|
|
) -> dict:
|
|
"""Submit a new render job to Flamenco Manager.
|
|
|
|
Returns the created job dict (includes 'id').
|
|
"""
|
|
payload = {
|
|
"name": name,
|
|
"type": job_type,
|
|
"submitter_platform": "linux",
|
|
"settings": settings,
|
|
"metadata": metadata or {},
|
|
"priority": priority,
|
|
}
|
|
resp = httpx.post(
|
|
self._url("/api/v3/jobs"),
|
|
json=payload,
|
|
timeout=DEFAULT_TIMEOUT,
|
|
)
|
|
resp.raise_for_status()
|
|
return resp.json()
|
|
|
|
def get_job(self, job_id: str) -> dict:
|
|
"""Get job details by ID."""
|
|
resp = httpx.get(
|
|
self._url(f"/api/v3/jobs/{job_id}"),
|
|
timeout=DEFAULT_TIMEOUT,
|
|
)
|
|
resp.raise_for_status()
|
|
return resp.json()
|
|
|
|
def cancel_job(self, job_id: str) -> None:
|
|
"""Request cancellation of a job."""
|
|
resp = httpx.post(
|
|
self._url(f"/api/v3/jobs/{job_id}/setstatus"),
|
|
json={"status": "cancel-requested"},
|
|
timeout=DEFAULT_TIMEOUT,
|
|
)
|
|
resp.raise_for_status()
|
|
|
|
# ── Workers ─────────────────────────────────────────────────────────────
|
|
|
|
def list_workers(self) -> list[dict]:
|
|
"""List all registered workers."""
|
|
resp = httpx.get(
|
|
self._url("/api/v3/worker-mgt/workers"),
|
|
timeout=DEFAULT_TIMEOUT,
|
|
)
|
|
resp.raise_for_status()
|
|
data = resp.json()
|
|
return data.get("workers", data) if isinstance(data, dict) else data
|
|
|
|
# ── Farm status ─────────────────────────────────────────────────────────
|
|
|
|
def get_farm_status(self) -> dict:
|
|
"""Get overall farm status from the Manager."""
|
|
resp = httpx.get(
|
|
self._url("/api/v3/configuration"),
|
|
timeout=DEFAULT_TIMEOUT,
|
|
)
|
|
resp.raise_for_status()
|
|
return resp.json()
|
|
|
|
def health_check(self) -> dict:
|
|
"""Check if the Flamenco Manager is reachable and return version info."""
|
|
try:
|
|
resp = httpx.get(
|
|
self._url("/api/v3/version"),
|
|
timeout=5.0,
|
|
)
|
|
resp.raise_for_status()
|
|
data = resp.json()
|
|
return {
|
|
"available": True,
|
|
"version": data.get("version", "unknown"),
|
|
"name": data.get("name", "Flamenco"),
|
|
}
|
|
except Exception as exc:
|
|
logger.warning(f"Flamenco health check failed: {exc}")
|
|
return {
|
|
"available": False,
|
|
"version": None,
|
|
"name": None,
|
|
"error": str(exc)[:200],
|
|
}
|
|
|
|
|
|
def get_flamenco_client(manager_url: str) -> FlamencoClient:
|
|
"""Factory that creates a FlamencoClient from a manager URL."""
|
|
return FlamencoClient(manager_url)
|