mirror of
https://github.com/langgenius/dify.git
synced 2026-09-08 11:04:27 +08:00
feat(api): add delete workflow functionality with error handling (#33657)
This commit is contained in:
parent
7dd802201f
commit
8a277da278
@ -53,6 +53,7 @@ from services.rag_pipeline.pipeline_generate_service import PipelineGenerateServ
|
|||||||
from services.rag_pipeline.rag_pipeline import RagPipelineService
|
from services.rag_pipeline.rag_pipeline import RagPipelineService
|
||||||
from services.rag_pipeline.rag_pipeline_manage_service import RagPipelineManageService
|
from services.rag_pipeline.rag_pipeline_manage_service import RagPipelineManageService
|
||||||
from services.rag_pipeline.rag_pipeline_transform_service import RagPipelineTransformService
|
from services.rag_pipeline.rag_pipeline_transform_service import RagPipelineTransformService
|
||||||
|
from services.workflow_service import DraftWorkflowDeletionError, WorkflowInUseError, WorkflowService
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
@ -781,7 +782,38 @@ class RagPipelineByIdApi(Resource):
|
|||||||
# Commit the transaction in the controller
|
# Commit the transaction in the controller
|
||||||
session.commit()
|
session.commit()
|
||||||
|
|
||||||
return workflow
|
return workflow
|
||||||
|
|
||||||
|
@setup_required
|
||||||
|
@login_required
|
||||||
|
@account_initialization_required
|
||||||
|
@edit_permission_required
|
||||||
|
@get_rag_pipeline
|
||||||
|
def delete(self, pipeline: Pipeline, workflow_id: str):
|
||||||
|
"""
|
||||||
|
Delete a published workflow version that is not currently active on the pipeline.
|
||||||
|
"""
|
||||||
|
if pipeline.workflow_id == workflow_id:
|
||||||
|
abort(400, description=f"Cannot delete workflow that is currently in use by pipeline '{pipeline.id}'")
|
||||||
|
|
||||||
|
workflow_service = WorkflowService()
|
||||||
|
|
||||||
|
with Session(db.engine) as session:
|
||||||
|
try:
|
||||||
|
workflow_service.delete_workflow(
|
||||||
|
session=session,
|
||||||
|
workflow_id=workflow_id,
|
||||||
|
tenant_id=pipeline.tenant_id,
|
||||||
|
)
|
||||||
|
session.commit()
|
||||||
|
except WorkflowInUseError as e:
|
||||||
|
abort(400, description=str(e))
|
||||||
|
except DraftWorkflowDeletionError as e:
|
||||||
|
abort(400, description=str(e))
|
||||||
|
except ValueError as e:
|
||||||
|
raise NotFound(str(e))
|
||||||
|
|
||||||
|
return None, 204
|
||||||
|
|
||||||
|
|
||||||
@console_ns.route("/rag/pipelines/<uuid:pipeline_id>/workflows/published/processing/parameters")
|
@console_ns.route("/rag/pipelines/<uuid:pipeline_id>/workflows/published/processing/parameters")
|
||||||
|
|||||||
@ -32,6 +32,7 @@ from extensions.ext_database import db
|
|||||||
# Configure logging for test containers
|
# Configure logging for test containers
|
||||||
logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(name)s - %(levelname)s - %(message)s")
|
logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(name)s - %(levelname)s - %(message)s")
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
_TEST_SANDBOX_IMAGE = os.getenv("TEST_SANDBOX_IMAGE", "langgenius/dify-sandbox:0.2.12")
|
||||||
|
|
||||||
DEFAULT_SANDBOX_TEST_IMAGE = "langgenius/dify-sandbox:0.2.14"
|
DEFAULT_SANDBOX_TEST_IMAGE = "langgenius/dify-sandbox:0.2.14"
|
||||||
SANDBOX_TEST_IMAGE_ENV = "DIFY_SANDBOX_TEST_IMAGE"
|
SANDBOX_TEST_IMAGE_ENV = "DIFY_SANDBOX_TEST_IMAGE"
|
||||||
|
|||||||
@ -2,7 +2,7 @@ from datetime import datetime
|
|||||||
from unittest.mock import MagicMock, patch
|
from unittest.mock import MagicMock, patch
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from werkzeug.exceptions import Forbidden, HTTPException, NotFound
|
from werkzeug.exceptions import BadRequest, Forbidden, HTTPException, NotFound
|
||||||
|
|
||||||
import services
|
import services
|
||||||
from controllers.console import console_ns
|
from controllers.console import console_ns
|
||||||
@ -692,6 +692,57 @@ class TestRagPipelineByIdApi:
|
|||||||
result, status = method(api, pipeline, "w1")
|
result, status = method(api, pipeline, "w1")
|
||||||
assert status == 400
|
assert status == 400
|
||||||
|
|
||||||
|
def test_delete_success(self, app):
|
||||||
|
api = RagPipelineByIdApi()
|
||||||
|
method = unwrap(api.delete)
|
||||||
|
|
||||||
|
pipeline = MagicMock(tenant_id="t1", workflow_id="active-workflow", id="pipeline-1")
|
||||||
|
|
||||||
|
workflow_service = MagicMock()
|
||||||
|
|
||||||
|
session = MagicMock()
|
||||||
|
session_ctx = MagicMock()
|
||||||
|
session_ctx.__enter__.return_value = session
|
||||||
|
session_ctx.__exit__.return_value = None
|
||||||
|
|
||||||
|
fake_db = MagicMock()
|
||||||
|
fake_db.engine = MagicMock()
|
||||||
|
|
||||||
|
with (
|
||||||
|
app.test_request_context("/", method="DELETE"),
|
||||||
|
patch(
|
||||||
|
"controllers.console.datasets.rag_pipeline.rag_pipeline_workflow.db",
|
||||||
|
fake_db,
|
||||||
|
),
|
||||||
|
patch(
|
||||||
|
"controllers.console.datasets.rag_pipeline.rag_pipeline_workflow.Session",
|
||||||
|
return_value=session_ctx,
|
||||||
|
),
|
||||||
|
patch(
|
||||||
|
"controllers.console.datasets.rag_pipeline.rag_pipeline_workflow.WorkflowService",
|
||||||
|
return_value=workflow_service,
|
||||||
|
),
|
||||||
|
):
|
||||||
|
result = method(api, pipeline, "old-workflow")
|
||||||
|
|
||||||
|
workflow_service.delete_workflow.assert_called_once_with(
|
||||||
|
session=session,
|
||||||
|
workflow_id="old-workflow",
|
||||||
|
tenant_id="t1",
|
||||||
|
)
|
||||||
|
session.commit.assert_called_once()
|
||||||
|
assert result == (None, 204)
|
||||||
|
|
||||||
|
def test_delete_active_workflow_rejected(self, app):
|
||||||
|
api = RagPipelineByIdApi()
|
||||||
|
method = unwrap(api.delete)
|
||||||
|
|
||||||
|
pipeline = MagicMock(tenant_id="t1", workflow_id="active-workflow", id="pipeline-1")
|
||||||
|
|
||||||
|
with app.test_request_context("/", method="DELETE"):
|
||||||
|
with pytest.raises(BadRequest, match="currently in use by pipeline"):
|
||||||
|
method(api, pipeline, "active-workflow")
|
||||||
|
|
||||||
|
|
||||||
class TestRagPipelineWorkflowLastRunApi:
|
class TestRagPipelineWorkflowLastRunApi:
|
||||||
def test_last_run_success(self, app):
|
def test_last_run_success(self, app):
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user