feat: add miner management endpoints and standardize all API paths to /api/v1 prefix

- Add POST /api/v1/miners/{miner_id}/jobs endpoint for listing miner-assigned jobs with filtering
- Add POST /api/v1/miners/{miner_id}/earnings endpoint for miner earnings tracking (mock implementation)
- Add PUT /api/v1/miners/{miner_id}/capabilities endpoint for updating miner capabilities
- Add DELETE /api/v1/miners/{miner_id} endpoint for miner deregistration (sets OFFLINE status)
- Add JobService.fail_job()
This commit is contained in:
oib
2026-03-05 11:12:57 +01:00
parent c2d4f39a36
commit 80b9ea4b25
11 changed files with 1664 additions and 85 deletions

View File

@@ -48,7 +48,7 @@ def submit(ctx, job_type: str, prompt: Optional[str], model: Optional[str],
try:
with httpx.Client() as client:
response = client.post(
f"{config.coordinator_url}/v1/jobs",
f"{config.coordinator_url}/api/v1/jobs",
headers={
"Content-Type": "application/json",
"X-Api-Key": config.api_key or ""
@@ -123,7 +123,7 @@ def blocks(ctx, limit: int):
try:
with httpx.Client() as client:
response = client.get(
f"{config.coordinator_url}/v1/blocks",
f"{config.coordinator_url}/api/v1/blocks",
params={"limit": limit},
headers={"X-Api-Key": config.api_key or ""}
)
@@ -273,7 +273,7 @@ def history(ctx, limit: int, status: Optional[str], type: Optional[str],
with httpx.Client() as client:
response = client.get(
f"{config.coordinator_url}/v1/jobs/history",
f"{config.coordinator_url}/api/v1/jobs",
params=params,
headers={"X-Api-Key": config.api_key or ""}
)

View File

@@ -49,7 +49,7 @@ def register(ctx, gpu: Optional[str], memory: Optional[int],
try:
with httpx.Client() as client:
response = client.post(
f"{config.coordinator_url}/v1/miners/register?miner_id={miner_id}",
f"{config.coordinator_url}/api/v1/miners/register?miner_id={miner_id}",
headers={
"Content-Type": "application/json",
"X-Api-Key": config.api_key or ""
@@ -80,7 +80,7 @@ def poll(ctx, wait: int, miner_id: str):
try:
with httpx.Client() as client:
response = client.post(
f"{config.coordinator_url}/v1/miners/poll",
f"{config.coordinator_url}/api/v1/miners/poll",
json={"max_wait_seconds": 5},
headers={
"X-Api-Key": config.api_key or "",
@@ -120,7 +120,7 @@ def mine(ctx, jobs: int, miner_id: str):
with httpx.Client() as client:
# Poll for job
response = client.post(
f"{config.coordinator_url}/v1/miners/poll",
f"{config.coordinator_url}/api/v1/miners/poll",
json={"max_wait_seconds": 5},
headers={
"X-Api-Key": config.api_key or "",
@@ -147,7 +147,7 @@ def mine(ctx, jobs: int, miner_id: str):
# Submit result
result_response = client.post(
f"{config.coordinator_url}/v1/miners/{job_id}/result",
f"{config.coordinator_url}/api/v1/miners/{job_id}/result",
headers={
"Content-Type": "application/json",
"X-Api-Key": config.api_key or "",
@@ -191,7 +191,7 @@ def heartbeat(ctx, miner_id: str):
try:
with httpx.Client() as client:
response = client.post(
f"{config.coordinator_url}/v1/miners/heartbeat?miner_id={miner_id}",
f"{config.coordinator_url}/api/v1/miners/heartbeat?miner_id={miner_id}",
headers={
"X-Api-Key": config.api_key or ""
},
@@ -244,7 +244,7 @@ def earnings(ctx, miner_id: str, from_time: Optional[str], to_time: Optional[str
with httpx.Client() as client:
response = client.post(
f"{config.coordinator_url}/v1/miners/{miner_id}/earnings",
f"{config.coordinator_url}/api/v1/miners/{miner_id}/earnings",
params=params,
headers={"X-Api-Key": config.api_key or ""}
)
@@ -290,7 +290,7 @@ def update_capabilities(ctx, gpu: Optional[str], memory: Optional[int],
try:
with httpx.Client() as client:
response = client.put(
f"{config.coordinator_url}/v1/miners/{miner_id}/capabilities",
f"{config.coordinator_url}/api/v1/miners/{miner_id}/capabilities",
headers={
"Content-Type": "application/json",
"X-Api-Key": config.api_key or ""
@@ -328,7 +328,7 @@ def deregister(ctx, miner_id: str, force: bool):
try:
with httpx.Client() as client:
response = client.delete(
f"{config.coordinator_url}/v1/miners/{miner_id}",
f"{config.coordinator_url}/api/v1/miners/{miner_id}",
headers={"X-Api-Key": config.api_key or ""}
)
@@ -368,7 +368,7 @@ def jobs(ctx, limit: int, job_type: Optional[str], min_reward: Optional[float],
with httpx.Client() as client:
response = client.post(
f"{config.coordinator_url}/v1/miners/{miner_id}/jobs",
f"{config.coordinator_url}/api/v1/miners/{miner_id}/jobs",
params=params,
headers={"X-Api-Key": config.api_key or ""}
)
@@ -389,7 +389,7 @@ def _process_single_job(config, miner_id: str, worker_id: int) -> Dict[str, Any]
try:
with httpx.Client() as http_client:
response = http_client.post(
f"{config.coordinator_url}/v1/miners/poll",
f"{config.coordinator_url}/api/v1/miners/poll",
json={"max_wait_seconds": 5},
headers={
"X-Api-Key": config.api_key or "",
@@ -407,7 +407,7 @@ def _process_single_job(config, miner_id: str, worker_id: int) -> Dict[str, Any]
time.sleep(2) # Simulate processing
result_response = http_client.post(
f"{config.coordinator_url}/v1/miners/{job_id}/result",
f"{config.coordinator_url}/api/v1/miners/{job_id}/result",
headers={
"Content-Type": "application/json",
"X-Api-Key": config.api_key or "",
@@ -484,7 +484,7 @@ def mine_ollama(ctx, jobs: int, miner_id: str, ollama_url: str, model: str):
try:
with httpx.Client() as client:
response = client.post(
f"{config.coordinator_url}/v1/miners/poll",
f"{config.coordinator_url}/api/v1/miners/poll",
json={"max_wait_seconds": 10},
headers={
"X-Api-Key": config.api_key or "",
@@ -528,7 +528,7 @@ def mine_ollama(ctx, jobs: int, miner_id: str, ollama_url: str, model: str):
error(f"Ollama inference failed: {ollama_result['error']}")
# Submit failure
client.post(
f"{config.coordinator_url}/v1/miners/{job_id}/fail",
f"{config.coordinator_url}/api/v1/miners/{job_id}/fail",
headers={
"Content-Type": "application/json",
"X-Api-Key": config.api_key or "",
@@ -540,7 +540,7 @@ def mine_ollama(ctx, jobs: int, miner_id: str, ollama_url: str, model: str):
# Submit successful result
result_response = client.post(
f"{config.coordinator_url}/v1/miners/{job_id}/result",
f"{config.coordinator_url}/api/v1/miners/{job_id}/result",
headers={
"Content-Type": "application/json",
"X-Api-Key": config.api_key or "",