feat: initial commit
This commit is contained in:
@@ -0,0 +1,121 @@
|
||||
"""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)
|
||||
Reference in New Issue
Block a user