Skip to content

Commit 069089c

Browse files
ActiveChooNCopilot
andauthored
feat(inspect): Delete model training job (#3206)
* feat(model): ensure associated training job is deleted when a model is removed Signed-off-by: Dmitry Kalinin <[email protected]> * Fixed linter Signed-off-by: Dmitry Kalinin <[email protected]> * Fixed linter Signed-off-by: Dmitry Kalinin <[email protected]> * Update application/backend/src/services/model_service.py Co-authored-by: Copilot <[email protected]> Signed-off-by: Dmitry Kalinin <[email protected]> --------- Signed-off-by: Dmitry Kalinin <[email protected]> Co-authored-by: Copilot <[email protected]>
1 parent d3ab907 commit 069089c

File tree

2 files changed

+33
-1
lines changed

2 files changed

+33
-1
lines changed

application/backend/src/services/model_service.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
from pydantic_models import Model, ModelList, PredictionLabel, PredictionResponse
2626
from pydantic_models.base import Pagination
2727
from pydantic_models.model import ExportParameters
28-
from repositories import ModelRepository
28+
from repositories import JobRepository, ModelRepository
2929
from repositories.binary_repo import ModelBinaryRepository, ModelExportBinaryRepository
3030
from services import ResourceNotFoundError
3131
from services.dataset_snapshot_service import DatasetSnapshotService
@@ -112,10 +112,16 @@ async def delete_model(cls, project_id: UUID, model_id: UUID) -> None:
112112
ds_snapshot_id = model.dataset_snapshot_id
113113
await DatasetSnapshotService.delete_snapshot_if_unused(snapshot_id=ds_snapshot_id, project_id=project_id)
114114

115+
train_job_id = model.train_job_id
116+
115117
async with get_async_db_session_ctx() as session:
116118
repo = ModelRepository(session, project_id=project_id)
117119
await repo.delete_by_id(model_id)
118120

121+
if train_job_id:
122+
job_repo = JobRepository(session)
123+
await job_repo.delete_by_id(train_job_id)
124+
119125
@classmethod
120126
async def delete_project_models_db(cls, session: AsyncSession, project_id: UUID, commit: bool = False) -> None:
121127
"""Delete all models associated with a project from the database."""

application/backend/tests/unit/services/test_model_service.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
# SPDX-License-Identifier: Apache-2.0
33
import asyncio
44
from unittest.mock import AsyncMock, MagicMock, patch
5+
from uuid import uuid4
56

67
import numpy as np
78
import openvino.properties.hint as ov_hints
@@ -151,6 +152,31 @@ def test_delete_model(self, fxt_model_service, fxt_model_repository, fxt_model,
151152
)
152153
mock_binary_repo.delete_model_folder.assert_called_once()
153154

155+
def test_delete_model_also_deletes_training_job(
156+
self, fxt_model_service, fxt_model_repository, fxt_model, fxt_project
157+
):
158+
"""Test that deleting a model also deletes its associated training job."""
159+
fxt_model_repository.delete_by_id.return_value = None
160+
fxt_model_repository.get_by_id.return_value = fxt_model
161+
fxt_model.train_job_id = uuid4()
162+
163+
with (
164+
patch("services.model_service.ModelRepository") as mock_repo_class,
165+
patch("services.model_service.JobRepository") as mock_job_repo_class,
166+
patch("services.model_service.DatasetSnapshotService") as mock_snapshot_service,
167+
patch("services.model_service.ModelBinaryRepository") as mock_binary_repo_class,
168+
):
169+
mock_repo_class.return_value = fxt_model_repository
170+
mock_job_repo = MagicMock()
171+
mock_job_repo.delete_by_id = AsyncMock()
172+
mock_job_repo_class.return_value = mock_job_repo
173+
mock_binary_repo_class.return_value.delete_model_folder = AsyncMock()
174+
mock_snapshot_service.delete_snapshot_if_unused = AsyncMock()
175+
176+
asyncio.run(fxt_model_service.delete_model(fxt_project.id, fxt_model.id))
177+
178+
mock_job_repo.delete_by_id.assert_called_once_with(fxt_model.train_job_id)
179+
154180
def test_load_inference_model_success(self, fxt_model_service, fxt_model, fxt_openvino_inferencer):
155181
"""Test loading inference model successfully."""
156182
with patch("services.model_service.ModelBinaryRepository") as mock_bin_repo_class:

0 commit comments

Comments
 (0)