Files
HartOMat/backend/app/services/flamenco_client.py
T
2026-03-05 22:12:38 +01:00

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)