service.py python
84 lines 3.1 KB
Raw
sha256:91e875d4a97bb1e35f37992f803988d5713931f1782d870c371c50054574af22 Add fixture provenance retention deletion Human minor ⚠ breaking 43 days ago
1 """Application service for Scooling Lab training API operations."""
2
3 from __future__ import annotations
4
5 from datetime import datetime
6 from typing import Iterable
7
8 from scooling_lab.contracts import (
9 TrainingJobRequest,
10 TrainingJobStatus,
11 require_artifact_id,
12 require_job_id,
13 )
14 from scooling_lab.fake_worker import FakeTrainingWorker
15 from scooling_lab.store import TrainingJobStore
16
17
18 class TrainingApiService:
19 """Implements the T2 API contract over a store and fake worker."""
20
21 def __init__(self, store: TrainingJobStore, auto_run_worker: bool = True) -> None:
22 """Create a service with optional synchronous fake-worker completion."""
23
24 self._store = store
25 self._worker = FakeTrainingWorker(store)
26 self._auto_run_worker = auto_run_worker
27
28 def create_training_job(self, payload: dict[str, object]) -> dict[str, object]:
29 """Validate, create, and optionally complete a fixture training job."""
30
31 request = TrainingJobRequest.from_mapping(payload)
32 job = self._store.create(request)
33 if self._auto_run_worker and job.status in {
34 TrainingJobStatus.QUEUED,
35 TrainingJobStatus.RUNNING,
36 }:
37 job = self._worker.run_job(job.id)
38 return job.to_public_dict()
39
40 def get_training_job(self, job_id: str) -> dict[str, object]:
41 """Return the public status for one training job."""
42
43 require_job_id(job_id)
44 return self._store.evaluate_expiry(job_id).to_public_dict()
45
46 def cancel_training_job(self, job_id: str) -> dict[str, object]:
47 """Cancel a queued or running training job."""
48
49 require_job_id(job_id)
50 return self._store.update_status(
51 job_id, TrainingJobStatus.CANCELLED
52 ).to_public_dict()
53
54 def list_artifacts(self, job_id: str) -> dict[str, object]:
55 """Return placeholder artifacts registered for one job."""
56
57 require_job_id(job_id)
58 self._store.evaluate_expiry(job_id)
59 artifacts = [artifact.to_dict() for artifact in self._store.list_artifacts(job_id)]
60 return {"jobId": job_id, "artifacts": artifacts}
61
62 def get_provenance(self, job_id: str) -> dict[str, object]:
63 """Return the validated provenance record for one completed fixture job."""
64
65 require_job_id(job_id)
66 self._store.evaluate_expiry(job_id)
67 return self._store.get_provenance(job_id).to_dict()
68
69 def delete_artifact(self, job_id: str, artifact_id: str) -> dict[str, object]:
70 """Delete an artifact and all derived content-bearing metadata."""
71
72 require_job_id(job_id)
73 require_artifact_id(artifact_id)
74 return self._store.delete_artifact(job_id, artifact_id).to_dict()
75
76 def sweep_expired_artifacts(self, now: datetime | None = None) -> dict[str, object]:
77 """Evaluate all retention policies and delete expired artifacts."""
78
79 return self._store.sweep_expired(now)
80
81 def verify_deleted_artifact_absence(self, hash_values: Iterable[str]) -> bool:
82 """Verify deleted artifact hashes are absent from all store outputs."""
83
84 return self._store.verify_hash_absence(hash_values)
File History 1 commit
sha256:91e875d4a97bb1e35f37992f803988d5713931f1782d870c371c50054574af22 Add fixture provenance retention deletion Human minor 43 days ago