Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/service api workflow logs #8323

Merged
merged 3 commits into from
Sep 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions api/controllers/service_api/app/workflow.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import logging

from flask_restful import Resource, fields, marshal_with, reqparse
from flask_restful.inputs import int_range
from werkzeug.exceptions import InternalServerError

from controllers.service_api import api
Expand All @@ -22,10 +23,12 @@
)
from core.model_runtime.errors.invoke import InvokeError
from extensions.ext_database import db
from fields.workflow_app_log_fields import workflow_app_log_pagination_fields
from libs import helper
from models.model import App, AppMode, EndUser
from models.workflow import WorkflowRun
from services.app_generate_service import AppGenerateService
from services.workflow_app_service import WorkflowAppService

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -113,6 +116,30 @@ def post(self, app_model: App, end_user: EndUser, task_id: str):
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(WorkflowRunDetailApi, "/workflows/run/<string:workflow_id>")
api.add_resource(WorkflowTaskStopApi, "/workflows/tasks/<string:task_id>/stop")
api.add_resource(WorkflowAppLogApi, "/workflows/logs")
106 changes: 106 additions & 0 deletions web/app/components/develop/template/template_workflow.en.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -413,3 +413,109 @@ Workflow applications offers non-session support and is ideal for translation, a
</CodeGroup>
</Col>
</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 changes: 106 additions & 0 deletions web/app/components/develop/template/template_workflow.zh.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -409,3 +409,109 @@ Workflow 应用无会话支持,适合用于翻译/文章写作/总结 AI 等
</CodeGroup>
</Col>
</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>