mirror of
https://github.com/langgenius/dify.git
synced 2026-04-05 06:19:25 +08:00
feat(api): add delete workflow functionality with error handling (#33657)
This commit is contained in:
@@ -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_manage_service import RagPipelineManageService
|
||||
from services.rag_pipeline.rag_pipeline_transform_service import RagPipelineTransformService
|
||||
from services.workflow_service import DraftWorkflowDeletionError, WorkflowInUseError, WorkflowService
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -781,7 +782,38 @@ class RagPipelineByIdApi(Resource):
|
||||
# Commit the transaction in the controller
|
||||
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")
|
||||
|
||||
@@ -32,6 +32,7 @@ from extensions.ext_database import db
|
||||
# Configure logging for test containers
|
||||
logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(name)s - %(levelname)s - %(message)s")
|
||||
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"
|
||||
SANDBOX_TEST_IMAGE_ENV = "DIFY_SANDBOX_TEST_IMAGE"
|
||||
|
||||
@@ -2,7 +2,7 @@ from datetime import datetime
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
||||
import pytest
|
||||
from werkzeug.exceptions import Forbidden, HTTPException, NotFound
|
||||
from werkzeug.exceptions import BadRequest, Forbidden, HTTPException, NotFound
|
||||
|
||||
import services
|
||||
from controllers.console import console_ns
|
||||
@@ -692,6 +692,57 @@ class TestRagPipelineByIdApi:
|
||||
result, status = method(api, pipeline, "w1")
|
||||
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:
|
||||
def test_last_run_success(self, app):
|
||||
|
||||
Reference in New Issue
Block a user