deerflow-code/offline-backend-20260512/backend/docs/PUBLIC_SCHEDULED_TASKS_API.md
2026-09-07 18:24:55 +08:00

279 lines
7.9 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 公开定时任务 API
本文档描述用于对接外部系统的**公开只读**定时任务接口,以及配套的公开网页入口。所有 `/api/public/*` 接口都**无需登录**,可以直接调用。
> ⚠️ 任何接入这套接口的系统需要确认:暴露 task / run 列表与正文是符合贵方业务安全要求的。如果不希望全员可见,请走带鉴权的 `/api/scheduled-tasks/*`。
---
## 1. 基础信息
| 项 | 值 |
|---|---|
| 网关基址(开发) | `http://localhost:8001` |
| 网关基址(生产) | 部署到 Nginx 后通常是 `https://<你的域名>` |
| 公开 API 前缀 | `/api/public/scheduled-tasks` |
| 鉴权 | **无需**鉴权(白名单在 `auth_middleware._PUBLIC_PATH_PREFIXES`) |
| 编码 | 请求 / 响应均为 UTF-8,响应类型 `application/json`(下载除外) |
| 错误响应 | 标准 FastAPI 错误体 `{"detail": "..."}`;HTTP 状态码 `404 / 400 / 500` 等 |
公开网页页面:
```
#/public/scheduled-tasks/<task_id>
```
例如 `https://<你的域名>/#/public/scheduled-tasks/8f1d8b9c-...`。
左侧列出该任务所有执行记录,默认打开第一条;右侧默认渲染 Markdown 正文,点击 Tab 可以查看“结果文件”或“元数据”,点击左侧任意记录右侧内容会跟随切换。
---
## 2. 接口列表
### 2.1 列出全部定时任务
```
GET /api/public/scheduled-tasks
```
**Query 参数**
| 名称 | 类型 | 必填 | 默认 | 说明 |
|---|---|---|---|---|
| `search` | string | 否 | — | 任务名模糊匹配(不区分大小写) |
| `limit` | int | 否 | 200 | 单页数量,1–500 |
| `offset` | int | 否 | 0 | 偏移量,配合 `limit` 分页 |
**响应**
```json
{
"total": 12,
"limit": 200,
"offset": 0,
"tasks": [
{
"task_id": "8f1d8b9c-...",
"name": "每日舆情简报",
"schedule_text": "每天 09:00",
"cron_expr": "0 9 * * *",
"timezone": "Asia/Shanghai",
"enabled": true,
"next_run_at": "2026-05-21T01:00:00+00:00",
"last_run_at": "2026-05-20T01:00:12+00:00",
"last_status": "succeeded",
"published": true
}
]
}
```
> 已脱敏:`user_id`、`creator_email`、`prompt`、`scheduler_thread_id`、`execution_context` 等私有字段不会出现在公开响应里。
### 2.2 获取单个任务元数据
```
GET /api/public/scheduled-tasks/{task_id}
```
**响应**:与上面 `tasks[]` 的元素结构一致;任务不存在返回 `404`。
### 2.3 列出某任务的所有执行记录
```
GET /api/public/scheduled-tasks/{task_id}/runs
```
**Query 参数**
| 名称 | 类型 | 必填 | 默认 | 说明 |
|---|---|---|---|---|
| `limit` | int | 否 | 50 | 最近执行数量,1–200 |
**响应**
```json
{
"task": { "task_id": "...", "name": "...", "schedule_text": "...", "timezone": "...", "enabled": true },
"total": 7,
"runs": [
{
"id": "run-uuid-...",
"task_id": "8f1d8b9c-...",
"scheduled_for": "2026-05-20T01:00:00+00:00",
"started_at": "2026-05-20T01:00:01+00:00",
"finished_at": "2026-05-20T01:00:12+00:00",
"status": "succeeded",
"error": null,
"retry_count": 0,
"result": {
"title": "2026-05-20 舆情简报",
"content": "# 简报\n\n...",
"format": "markdown",
"files": [
{ "index": 0, "name": "report.md", "mime_type": "text/markdown", "kind": "markdown", "size": 4321 }
],
"created_at": "2026-05-20T01:00:12+00:00"
}
}
]
}
```
> 已脱敏:返回的 `files[]` 不包含服务器绝对路径;客户端通过下标 `index` 调用文件接口。
### 2.4 获取单条执行记录
```
GET /api/public/scheduled-tasks/runs/{run_id}
```
返回单条 run 数据(结构同 2.3 中的 `runs[]` 元素)。
### 2.5 获取单个结果文件的内容(可预览文本直接内联)
```
GET /api/public/scheduled-tasks/runs/{run_id}/files/{file_index}
```
`file_index` 来自 `run.result.files[].index`。
**响应**
```json
{
"index": 0,
"name": "report.md",
"mime_type": "text/markdown",
"kind": "markdown",
"size": 4321,
"previewable": true,
"content": "# 简报\n\n..."
}
```
二进制文件 `previewable=false`、`content=null`,请走 2.6 下载。
### 2.6 下载单个结果文件
```
GET /api/public/scheduled-tasks/runs/{run_id}/files/{file_index}/download
```
返回原始文件二进制流,附带 `Content-Disposition: attachment` 头部。
### 2.7 打包下载整个执行结果
```
GET /api/public/scheduled-tasks/runs/{run_id}/download
```
- 如果该 run **没有附加文件**:直接返回 `result.md`(UTF-8 BOM)。
- 如果有 ≥ 1 个附加文件:返回 ZIP,里面包含:
- `result.md` — 标题 + 正文 Markdown
- 每个生成文件原样
---
## 3. 调用示例
### curl
```bash
# 列出全部任务
curl -s "https://<domain>/api/public/scheduled-tasks?limit=50"
# 查看任务的执行记录
curl -s "https://<domain>/api/public/scheduled-tasks/<task_id>/runs"
# 下载某次执行
curl -L -o report.zip \
"https://<domain>/api/public/scheduled-tasks/runs/<run_id>/download"
```
### Python
```python
import requests
base = "https://<domain>/api/public/scheduled-tasks"
tasks = requests.get(f"{base}", params={"limit": 100, "search": "舆情"}).json()
for task in tasks["tasks"]:
runs = requests.get(f"{base}/{task['task_id']}/runs", params={"limit": 5}).json()
for run in runs["runs"]:
if run.get("result"):
print(task["name"], run["id"], run["result"]["title"])
print(run["result"]["content"][:200])
```
### 直接嵌入 iframe
```html
<iframe src="https://<domain>/#/public/scheduled-tasks/<task_id>"
style="width:100%;height:800px;border:0"></iframe>
```
---
## 4. 状态码
| 状态码 | 含义 |
|---|---|
| 200 | 成功 |
| 400 | 参数错误(如 `limit` 超出范围) |
| 404 | 任务 / 执行 / 文件 不存在 |
| 5xx | 网关 / 后台错误 |
---
## 5. 字段映射快查
### `task` 字段
| 字段 | 类型 | 说明 |
|---|---|---|
| `task_id` | string | 任务 ID |
| `name` | string | 任务名 |
| `schedule_text` | string | 人类可读的执行计划 |
| `cron_expr` | string | 规范化的 cron 表达式 |
| `timezone` | string | 时区 |
| `enabled` | bool | 是否启用 |
| `next_run_at` | string &#124; null | 下次执行时间(ISO 8601) |
| `last_run_at` | string &#124; null | 上次执行时间 |
| `last_status` | string &#124; null | 上次执行状态(`succeeded` / `failed` / `running` / `pending` / `…`) |
| `published` | bool | 是否被发布到广场 |
### `run` 字段
| 字段 | 类型 | 说明 |
|---|---|---|
| `id` | string | 执行 ID |
| `task_id` | string | 所属任务 ID |
| `scheduled_for` | string | 原定执行时间 |
| `started_at` | string &#124; null | 实际开始时间 |
| `finished_at` | string &#124; null | 完成 / 失败时间 |
| `status` | string | `pending` / `running` / `succeeded` / `failed` |
| `error` | string &#124; null | 失败描述 |
| `retry_count` | int &#124; null | 重试次数 |
| `result` | object &#124; null | 执行结果(见下) |
### `result` 字段
| 字段 | 类型 | 说明 |
|---|---|---|
| `title` | string | 结果标题 |
| `content` | string | 主体 Markdown / 文本 |
| `format` | string | `markdown` / `text` / `json` / `mixed` |
| `files[]` | array | 附加文件元数据,含 `index / name / mime_type / kind / size` |
| `created_at` | string | 结果生成时间 |
---
## 6. 实现位置
- 路由实现:[`app/gateway/routers/public_scheduled_tasks.py`](../app/gateway/routers/public_scheduled_tasks.py)
- 公开 URL 白名单:[`app/gateway/auth_middleware.py`](../app/gateway/auth_middleware.py) 中的 `_PUBLIC_PATH_PREFIXES`
- 前端公开页面:[`frontend-web/src/pages/PublicScheduledTaskPage.tsx`](../../../frontend-web/src/pages/PublicScheduledTaskPage.tsx)
- 路由注册:[`frontend-web/src/App.tsx`](../../../frontend-web/src/App.tsx) `/#/public/scheduled-tasks/:taskId`