feat: initial commit

This commit is contained in:
2026-03-05 22:12:38 +01:00
commit bce762a783
380 changed files with 51955 additions and 0 deletions
+121
View File
@@ -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)