From afe95fa7804464a6eda19bd71ac8d58ddcc78e14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=9D=9E=E6=B3=95=E6=93=8D=E4=BD=9C?= Date: Thu, 18 Jul 2024 15:06:14 +0800 Subject: [PATCH] feat: support get workflow task execution status (#6411) --- api/controllers/service_api/app/workflow.py | 33 ++++++++++- .../develop/template/template_workflow.en.mdx | 57 +++++++++++++++++++ .../develop/template/template_workflow.zh.mdx | 57 +++++++++++++++++++ 3 files changed, 145 insertions(+), 2 deletions(-) diff --git a/api/controllers/service_api/app/workflow.py b/api/controllers/service_api/app/workflow.py index dd11949e84..10484c9027 100644 --- a/api/controllers/service_api/app/workflow.py +++ b/api/controllers/service_api/app/workflow.py @@ -1,6 +1,6 @@ import logging -from flask_restful import Resource, reqparse +from flask_restful import Resource, fields, marshal_with, reqparse from werkzeug.exceptions import InternalServerError from controllers.service_api import api @@ -21,14 +21,43 @@ from core.errors.error import ( QuotaExceededError, ) from core.model_runtime.errors.invoke import InvokeError +from extensions.ext_database import db from libs import helper from models.model import App, AppMode, EndUser +from models.workflow import WorkflowRun from services.app_generate_service import AppGenerateService logger = logging.getLogger(__name__) class WorkflowRunApi(Resource): + workflow_run_fields = { + 'id': fields.String, + 'workflow_id': fields.String, + 'status': fields.String, + 'inputs': fields.Raw, + 'outputs': fields.Raw, + 'error': fields.String, + 'total_steps': fields.Integer, + 'total_tokens': fields.Integer, + 'created_at': fields.DateTime, + 'finished_at': fields.DateTime, + 'elapsed_time': fields.Float, + } + + @validate_app_token + @marshal_with(workflow_run_fields) + def get(self, app_model: App, workflow_id: str): + """ + Get a workflow task running detail + """ + app_mode = AppMode.value_of(app_model.mode) + if app_mode != AppMode.WORKFLOW: + raise NotWorkflowAppError() + + workflow_run = db.session.query(WorkflowRun).filter(WorkflowRun.id == workflow_id).first() + return workflow_run + @validate_app_token(fetch_user_arg=FetchUserArg(fetch_from=WhereisUserArg.JSON, required=True)) def post(self, app_model: App, end_user: EndUser): """ @@ -88,5 +117,5 @@ class WorkflowTaskStopApi(Resource): } -api.add_resource(WorkflowRunApi, '/workflows/run') +api.add_resource(WorkflowRunApi, '/workflows/run/', '/workflows/run') api.add_resource(WorkflowTaskStopApi, '/workflows/tasks//stop') diff --git a/web/app/components/develop/template/template_workflow.en.mdx b/web/app/components/develop/template/template_workflow.en.mdx index 64a9092f59..1c86aad508 100644 --- a/web/app/components/develop/template/template_workflow.en.mdx +++ b/web/app/components/develop/template/template_workflow.en.mdx @@ -224,6 +224,63 @@ Workflow applications offers non-session support and is ideal for translation, a --- + + + + Retrieve the current execution results of a workflow task based on the workflow execution ID. + ### Path + - `workflow_id` (string) Workflow ID, can be obtained from the streaming chunk return + ### Response + - `id` (string) ID of workflow execution + - `workflow_id` (string) ID of relatied workflow + - `status` (string) status of execution, `running` / `succeeded` / `failed` / `stopped` + - `inputs` (json) content of input + - `outputs` (json) content of output + - `error` (string) reason of error + - `total_steps` (int) total steps of task + - `total_tokens` (int) total tokens to be used + - `created_at` (timestamp) start time + - `finished_at` (timestamp) end time + - `elapsed_time` (float) total seconds to be used + + + ### Request Example + + ```bash {{ title: 'cURL' }} + curl -X GET '${props.appDetail.api_base_url}/workflows/run/:workflow_id' \ + -H 'Authorization: Bearer {api_key}' \ + -H 'Content-Type: application/json' + ``` + + + ### Response Example + + ```json {{ title: 'Response' }} + { + "id": "b1ad3277-089e-42c6-9dff-6820d94fbc76", + "workflow_id": "19eff89f-ec03-4f75-b0fc-897e7effea02", + "status": "succeeded", + "inputs": "{\"sys.files\": [], \"sys.user_id\": \"abc-123\"}", + "outputs": null, + "error": null, + "total_steps": 3, + "total_tokens": 0, + "created_at": "Thu, 18 Jul 2024 03:17:40 -0000", + "finished_at": "Thu, 18 Jul 2024 03:18:10 -0000", + "elapsed_time": 30.098514399956912 + } + ``` + + + + +--- + + + + 根据 workflow 执行 ID 获取 workflow 任务当前执行结果 + ### Path + - `workflow_id` (string) workflow 执行 ID,可在流式返回 Chunk 中获取 + ### Response + - `id` (string) workflow 执行 ID + - `workflow_id` (string) 关联的 Workflow ID + - `status` (string) 执行状态 `running` / `succeeded` / `failed` / `stopped` + - `inputs` (json) 任务输入内容 + - `outputs` (json) 任务输出内容 + - `error` (string) 错误原因 + - `total_steps` (int) 任务执行总步数 + - `total_tokens` (int) 任务执行总 tokens + - `created_at` (timestamp) 任务开始时间 + - `finished_at` (timestamp) 任务结束时间 + - `elapsed_time` (float) 耗时(s) + + + ### Request Example + + ```bash {{ title: 'cURL' }} + curl -X GET '${props.appDetail.api_base_url}/workflows/run/:workflow_id' \ + -H 'Authorization: Bearer {api_key}' \ + -H 'Content-Type: application/json' + ``` + + + ### Response Example + + ```json {{ title: 'Response' }} + { + "id": "b1ad3277-089e-42c6-9dff-6820d94fbc76", + "workflow_id": "19eff89f-ec03-4f75-b0fc-897e7effea02", + "status": "succeeded", + "inputs": "{\"sys.files\": [], \"sys.user_id\": \"abc-123\"}", + "outputs": null, + "error": null, + "total_steps": 3, + "total_tokens": 0, + "created_at": "Thu, 18 Jul 2024 03:17:40 -0000", + "finished_at": "Thu, 18 Jul 2024 03:18:10 -0000", + "elapsed_time": 30.098514399956912 + } + ``` + + + + +--- +