Explorar o código

Feature/service api workflow logs (#8323)

fanlia hai 8 meses
pai
achega
5f03e66489

+ 27 - 0
api/controllers/service_api/app/workflow.py

@@ -1,6 +1,7 @@
 import logging
 import logging
 
 
 from flask_restful import Resource, fields, marshal_with, reqparse
 from flask_restful import Resource, fields, marshal_with, reqparse
+from flask_restful.inputs import int_range
 from werkzeug.exceptions import InternalServerError
 from werkzeug.exceptions import InternalServerError
 
 
 from controllers.service_api import api
 from controllers.service_api import api
@@ -22,10 +23,12 @@ from core.errors.error import (
 )
 )
 from core.model_runtime.errors.invoke import InvokeError
 from core.model_runtime.errors.invoke import InvokeError
 from extensions.ext_database import db
 from extensions.ext_database import db
+from fields.workflow_app_log_fields import workflow_app_log_pagination_fields
 from libs import helper
 from libs import helper
 from models.model import App, AppMode, EndUser
 from models.model import App, AppMode, EndUser
 from models.workflow import WorkflowRun
 from models.workflow import WorkflowRun
 from services.app_generate_service import AppGenerateService
 from services.app_generate_service import AppGenerateService
+from services.workflow_app_service import WorkflowAppService
 
 
 logger = logging.getLogger(__name__)
 logger = logging.getLogger(__name__)
 
 
@@ -113,6 +116,30 @@ class WorkflowTaskStopApi(Resource):
         return {"result": "success"}
         return {"result": "success"}
 
 
 
 
+class WorkflowAppLogApi(Resource):
+    @validate_app_token
+    @marshal_with(workflow_app_log_pagination_fields)
+    def get(self, app_model: App):
+        """
+        Get workflow app logs
+        """
+        parser = reqparse.RequestParser()
+        parser.add_argument("keyword", type=str, location="args")
+        parser.add_argument("status", type=str, choices=["succeeded", "failed", "stopped"], location="args")
+        parser.add_argument("page", type=int_range(1, 99999), default=1, location="args")
+        parser.add_argument("limit", type=int_range(1, 100), default=20, location="args")
+        args = parser.parse_args()
+
+        # get paginate workflow app logs
+        workflow_app_service = WorkflowAppService()
+        workflow_app_log_pagination = workflow_app_service.get_paginate_workflow_app_logs(
+            app_model=app_model, args=args
+        )
+
+        return workflow_app_log_pagination
+
+
 api.add_resource(WorkflowRunApi, "/workflows/run")
 api.add_resource(WorkflowRunApi, "/workflows/run")
 api.add_resource(WorkflowRunDetailApi, "/workflows/run/<string:workflow_id>")
 api.add_resource(WorkflowRunDetailApi, "/workflows/run/<string:workflow_id>")
 api.add_resource(WorkflowTaskStopApi, "/workflows/tasks/<string:task_id>/stop")
 api.add_resource(WorkflowTaskStopApi, "/workflows/tasks/<string:task_id>/stop")
+api.add_resource(WorkflowAppLogApi, "/workflows/logs")

+ 106 - 0
web/app/components/develop/template/template_workflow.en.mdx

@@ -413,3 +413,109 @@ Workflow applications offers non-session support and is ideal for translation, a
     </CodeGroup>
     </CodeGroup>
   </Col>
   </Col>
 </Row>
 </Row>
+
+---
+
+<Heading
+  url='/workflows/logs'
+  method='GET'
+  title='Get workflow logs'
+  name='#Get-Workflow-Logs'
+/>
+<Row>
+  <Col>
+    Returns worklfow logs, with the first page returning the latest `{limit}` messages, i.e., in reverse order.
+
+    ### Query
+
+    <Properties>
+      <Property name='keyword' type='string' key='keyword'>
+        Keyword to search
+      </Property>
+      <Property name='status' type='string' key='status'>
+        succeeded/failed/stopped
+      </Property>
+      <Property name='page' type='int' key='page'>
+        current page, default is 1.
+      </Property>
+      <Property name='limit' type='int' key='limit'>
+          How many chat history messages to return in one request, default is 20.
+      </Property>
+    </Properties>
+
+    ### Response
+  - `page` (int) Current page
+  - `limit` (int) Number of returned items, if input exceeds system limit, returns system limit amount
+  - `total` (int) Number of total items
+  - `has_more` (bool) Whether there is a next page
+  - `data` (array[object]) Log list
+    - `id` (string) ID
+    - `workflow_run` (object) Workflow run
+      - `id` (string) ID
+      - `version` (string) Version
+      - `status` (string) status of execution, `running` / `succeeded` / `failed` / `stopped`
+      - `error` (string) Optional reason of error
+      - `elapsed_time` (float) total seconds to be used
+      - `total_tokens` (int) tokens to be used
+      - `total_steps` (int) default 0
+      - `created_at` (timestamp) start time
+      - `finished_at` (timestamp) end time
+    - `created_from` (string) Created from
+    - `created_by_role` (string) Created by role
+    - `created_by_account` (string) Optional Created by account
+    - `created_by_end_user` (object) Created by end user
+      - `id` (string) ID
+      - `type` (string) Type
+      - `is_anonymous` (bool) Is anonymous
+      - `session_id` (string) Session ID
+    - `created_at` (timestamp) create time
+  </Col>
+  <Col sticky>
+
+    <CodeGroup title="Request" tag="GET" label="/workflows/logs" targetCode={`curl -X GET '${props.appDetail.api_base_url}/workflows/logs'\\\n --header 'Authorization: Bearer {api_key}'`}>
+
+    ```bash {{ title: 'cURL' }}
+    curl -X GET '${props.appDetail.api_base_url}/workflows/logs?limit=1'
+    --header 'Authorization: Bearer {api_key}'
+    ```
+
+    </CodeGroup>
+    ### Response Example
+    <CodeGroup title="Response">
+    ```json {{ title: 'Response' }}
+    {
+        "page": 1,
+        "limit": 1,
+        "total": 7,
+        "has_more": true,
+        "data": [
+            {
+                "id": "e41b93f1-7ca2-40fd-b3a8-999aeb499cc0",
+                "workflow_run": {
+                    "id": "c0640fc8-03ef-4481-a96c-8a13b732a36e",
+                    "version": "2024-08-01 12:17:09.771832",
+                    "status": "succeeded",
+                    "error": null,
+                    "elapsed_time": 1.3588523610014818,
+                    "total_tokens": 0,
+                    "total_steps": 3,
+                    "created_at": 1726139643,
+                    "finished_at": 1726139644
+                },
+                "created_from": "service-api",
+                "created_by_role": "end_user",
+                "created_by_account": null,
+                "created_by_end_user": {
+                    "id": "7f7d9117-dd9d-441d-8970-87e5e7e687a3",
+                    "type": "service_api",
+                    "is_anonymous": false,
+                    "session_id": "abc-123"
+                },
+                "created_at": 1726139644
+            }
+        ]
+    }
+    ```
+    </CodeGroup>
+  </Col>
+</Row>

+ 106 - 0
web/app/components/develop/template/template_workflow.zh.mdx

@@ -409,3 +409,109 @@ Workflow 应用无会话支持,适合用于翻译/文章写作/总结 AI 等
     </CodeGroup>
     </CodeGroup>
   </Col>
   </Col>
 </Row>
 </Row>
+
+---
+
+<Heading
+  url='/workflows/logs'
+  method='GET'
+  title='获取 workflow 日志'
+  name='#Get-Workflow-Logs'
+/>
+<Row>
+  <Col>
+    倒序返回workflow日志
+
+    ### Query
+
+    <Properties>
+      <Property name='keyword' type='string' key='keyword'>
+        关键字
+      </Property>
+      <Property name='status' type='string' key='status'>
+        执行状态 succeeded/failed/stopped
+      </Property>
+      <Property name='page' type='int' key='page'>
+        当前页码, 默认1.
+      </Property>
+      <Property name='limit' type='int' key='limit'>
+        每页条数, 默认20.
+      </Property>
+    </Properties>
+
+    ### Response
+  - `page` (int) 当前页码
+  - `limit` (int) 每页条数
+  - `total` (int) 总条数
+  - `has_more` (bool) 是否还有更多数据
+  - `data` (array[object]) 当前页码的数据
+    - `id` (string) 标识
+    - `workflow_run` (object) Workflow 执行日志
+      - `id` (string) 标识
+      - `version` (string) 版本
+      - `status` (string) 执行状态, `running` / `succeeded` / `failed` / `stopped`
+      - `error` (string) (可选) 错误
+      - `elapsed_time` (float) 耗时,单位秒
+      - `total_tokens` (int) 消耗的token数量
+      - `total_steps` (int) 执行步骤长度
+      - `created_at` (timestamp) 开始时间
+      - `finished_at` (timestamp) 结束时间
+    - `created_from` (string) 来源
+    - `created_by_role` (string) 角色
+    - `created_by_account` (string) (可选) 帐号
+    - `created_by_end_user` (object) 用户
+      - `id` (string) 标识
+      - `type` (string) 类型
+      - `is_anonymous` (bool) 是否匿名
+      - `session_id` (string) 会话标识
+    - `created_at` (timestamp) 创建时间
+  </Col>
+  <Col sticky>
+
+    <CodeGroup title="Request" tag="GET" label="/workflows/logs" targetCode={`curl -X GET '${props.appDetail.api_base_url}/workflows/logs'\\\n --header 'Authorization: Bearer {api_key}'`}>
+
+    ```bash {{ title: 'cURL' }}
+    curl -X GET '${props.appDetail.api_base_url}/workflows/logs?limit=1'
+    --header 'Authorization: Bearer {api_key}'
+    ```
+
+    </CodeGroup>
+    ### Response Example
+    <CodeGroup title="Response">
+    ```json {{ title: 'Response' }}
+    {
+        "page": 1,
+        "limit": 1,
+        "total": 7,
+        "has_more": true,
+        "data": [
+            {
+                "id": "e41b93f1-7ca2-40fd-b3a8-999aeb499cc0",
+                "workflow_run": {
+                    "id": "c0640fc8-03ef-4481-a96c-8a13b732a36e",
+                    "version": "2024-08-01 12:17:09.771832",
+                    "status": "succeeded",
+                    "error": null,
+                    "elapsed_time": 1.3588523610014818,
+                    "total_tokens": 0,
+                    "total_steps": 3,
+                    "created_at": 1726139643,
+                    "finished_at": 1726139644
+                },
+                "created_from": "service-api",
+                "created_by_role": "end_user",
+                "created_by_account": null,
+                "created_by_end_user": {
+                    "id": "7f7d9117-dd9d-441d-8970-87e5e7e687a3",
+                    "type": "service_api",
+                    "is_anonymous": false,
+                    "session_id": "abc-123"
+                },
+                "created_at": 1726139644
+            }
+        ]
+    }
+    ```
+    </CodeGroup>
+  </Col>
+</Row>