diff --git a/silo_client/__init__.py b/silo_client/__init__.py index 9a3c71e..1828153 100644 --- a/silo_client/__init__.py +++ b/silo_client/__init__.py @@ -941,3 +941,85 @@ class SiloClient: if revision_number is not None: path += f"?revision={revision_number}" return self._request("GET", path) + + # -- Jobs --------------------------------------------------------------- + + def list_jobs( + self, + status: str = "", + item_id: str = "", + definition: str = "", + limit: int = 100, + ) -> list: + """List jobs, optionally filtered by status, item, or definition.""" + params = [f"limit={limit}"] + if status: + params.append(f"status={urllib.parse.quote(status)}") + if item_id: + params.append(f"item_id={urllib.parse.quote(item_id)}") + if definition: + params.append(f"definition={urllib.parse.quote(definition)}") + return self._request("GET", "/jobs?" + "&".join(params)) + + def get_job(self, job_id: str) -> Dict[str, Any]: + """Get details for a specific job.""" + return self._request("GET", f"/jobs/{urllib.parse.quote(job_id, safe='')}") + + def get_job_logs(self, job_id: str) -> list: + """Get log entries for a job.""" + return self._request("GET", f"/jobs/{urllib.parse.quote(job_id, safe='')}/logs") + + def trigger_job( + self, + definition_name: str, + part_number: str = "", + item_id: str = "", + ) -> Dict[str, Any]: + """Manually trigger a job. + + Either *part_number* or *item_id* should identify the target item. + """ + data: Dict[str, Any] = {"definition_name": definition_name} + if part_number: + data["part_number"] = part_number + if item_id: + data["item_id"] = item_id + return self._request("POST", "/jobs", data) + + def cancel_job(self, job_id: str) -> Dict[str, Any]: + """Cancel a pending or running job.""" + return self._request( + "POST", f"/jobs/{urllib.parse.quote(job_id, safe='')}/cancel" + ) + + # -- Job Definitions ---------------------------------------------------- + + def list_job_definitions(self) -> list: + """List all loaded job definitions.""" + return self._request("GET", "/job-definitions") + + def get_job_definition(self, name: str) -> Dict[str, Any]: + """Get a specific job definition by name.""" + return self._request( + "GET", f"/job-definitions/{urllib.parse.quote(name, safe='')}" + ) + + def reload_job_definitions(self) -> Dict[str, Any]: + """Re-read YAML job definitions from disk (admin only).""" + return self._request("POST", "/job-definitions/reload") + + # -- Runners (admin) ---------------------------------------------------- + + def list_runners(self) -> list: + """List all registered runners.""" + return self._request("GET", "/runners") + + def register_runner(self, name: str, tags: List[str]) -> Dict[str, Any]: + """Register a new runner. Returns the token (shown once).""" + return self._request("POST", "/runners", {"name": name, "tags": tags}) + + def delete_runner(self, runner_id: str) -> None: + """Delete a registered runner.""" + self._request( + "DELETE", f"/runners/{urllib.parse.quote(runner_id, safe='')}", raw=True + )