Files
dify/api/controllers/console/explore/workflow.py
T

133 lines
5.4 KiB
Python

import logging
from http import HTTPStatus
from flask import Response
from flask_restx import Resource
from controllers.common.controller_schemas import WorkflowRunPayload as BaseWorkflowRunPayload
from controllers.common.errors import InternalServerError, UnauthorizedError
from controllers.common.fields import SimpleResultResponse
from controllers.common.schema import register_response_schema_models, register_schema_model
from controllers.console import console_ns
from controllers.console.app.error import (
CompletionRequestError,
ProviderModelCurrentlyNotSupportError,
ProviderNotInitializeError,
ProviderQuotaExceededError,
)
from controllers.console.explore.connections import installed_connection_errors
from controllers.console.explore.error import NotWorkflowAppError
from controllers.console.explore.installed_app_admission import get_installed_app
from controllers.console.flask_admission import console_account_admission
from controllers.console.wraps import model_validate
from controllers.web.error import InvokeRateLimitError as InvokeRateLimitHttpError
from core.errors.error import (
ModelCurrentlyNotSupportError,
ProviderTokenNotInitError,
QuotaExceededError,
)
from extensions.ext_application_services import application_services
from graphon.model_runtime.errors.invoke import InvokeError
from libs import helper
from libs.external_api import error_responses
from machinery.context import RequestContext
from models.model import AppMode
from services.account_errors import AccountNotFoundError
from services.app_definition_query_service import AppDefinitionUnavailableError
from services.end_user_connections.errors import ConnectionError
from services.end_user_connections.execution import ConnectionRunInput
from services.errors.llm import InvokeRateLimitError
from services.installed_app_access_service import InstalledAppRef
from services.installed_app_generation_service import InstalledAppNotWorkflowError
logger = logging.getLogger(__name__)
class InstalledAppWorkflowRunPayload(BaseWorkflowRunPayload, ConnectionRunInput):
pass
register_schema_model(console_ns, InstalledAppWorkflowRunPayload)
register_response_schema_models(console_ns, SimpleResultResponse)
@console_ns.route("/installed-apps/<uuid:installed_app_id>/workflows/run")
class InstalledAppWorkflowRunApi(Resource):
@error_responses(
CompletionRequestError,
InvokeRateLimitHttpError,
NotWorkflowAppError,
ProviderModelCurrentlyNotSupportError,
ProviderNotInitializeError,
ProviderQuotaExceededError,
)
@console_ns.expect(console_ns.models[InstalledAppWorkflowRunPayload.__name__])
@console_ns.response(HTTPStatus.OK, "Success")
@console_account_admission()
@get_installed_app
@model_validate(InstalledAppWorkflowRunPayload)
@installed_connection_errors
def post(
self,
req_data: InstalledAppWorkflowRunPayload,
request_context: RequestContext,
installed_app: InstalledAppRef,
) -> Response:
"""
Run workflow
"""
try:
response = application_services().installed_apps.generation.generate_workflow(
installed_app=installed_app,
account_id=request_context.account_id,
args=req_data.model_dump(mode="json", exclude_none=True),
)
# response-contract:ignore compact_generate_response
return helper.compact_generate_response(response)
except ConnectionError:
raise
except (AppDefinitionUnavailableError, InstalledAppNotWorkflowError):
raise NotWorkflowAppError() from None
except AccountNotFoundError:
raise UnauthorizedError("Account no longer exists.") from None
except ProviderTokenNotInitError as ex:
raise ProviderNotInitializeError(ex.description) from ex
except QuotaExceededError as caught_error:
raise ProviderQuotaExceededError() from caught_error
except ModelCurrentlyNotSupportError as caught_error:
raise ProviderModelCurrentlyNotSupportError() from caught_error
except InvokeError as e:
raise CompletionRequestError(e.description) from e
except InvokeRateLimitError as ex:
raise InvokeRateLimitHttpError(ex.description) from ex
except ValueError as e:
raise e
except Exception as caught_error:
logger.exception("internal server error.")
raise InternalServerError() from caught_error
@console_ns.route("/installed-apps/<uuid:installed_app_id>/workflows/tasks/<string:task_id>/stop")
class InstalledAppWorkflowTaskStopApi(Resource):
@error_responses(NotWorkflowAppError)
@console_ns.response(HTTPStatus.OK, "Success", console_ns.models[SimpleResultResponse.__name__])
@console_account_admission()
@get_installed_app
def post(self, request_context: RequestContext, installed_app: InstalledAppRef, task_id: str) -> dict[str, object]:
"""
Stop workflow task
"""
if installed_app.app_mode != "workflow":
raise NotWorkflowAppError()
application_services().app_tasks.stop_workflow_task(
tenant_id=installed_app.app_owner_tenant_id,
app_id=installed_app.app_id,
task_id=task_id,
app_mode=AppMode.WORKFLOW,
owner=None,
)
return SimpleResultResponse(result="success").model_dump(mode="json")