feat: harden deployment and public api handoff
This commit is contained in:
293
docs/API.md
Normal file
293
docs/API.md
Normal file
@@ -0,0 +1,293 @@
|
||||
# 智念AIGC平台开放 API 对接说明
|
||||
|
||||
本文面向服务端对接方。所有开放接口位于 `/api/v1`,使用 API Key 鉴权。
|
||||
|
||||
OpenAPI JSON:
|
||||
|
||||
```text
|
||||
GET /api/v1/openapi.json
|
||||
```
|
||||
|
||||
## 鉴权
|
||||
|
||||
支持两种方式,任选一种:
|
||||
|
||||
```http
|
||||
Authorization: Bearer <API_KEY>
|
||||
```
|
||||
|
||||
或:
|
||||
|
||||
```http
|
||||
X-Zhinian-Api-Key: <API_KEY>
|
||||
```
|
||||
|
||||
服务端配置示例:
|
||||
|
||||
```env
|
||||
ZHINIAN_API_KEYS=partner-a:key-a,partner-b:key-b
|
||||
```
|
||||
|
||||
冒号前是 clientId,冒号后是 API Key。任务和资产会按 clientId 做基本隔离。
|
||||
|
||||
## 任务生命周期
|
||||
|
||||
创建任务后不会同步生成结果,而是进入任务队列:
|
||||
|
||||
```text
|
||||
queued -> running -> succeeded
|
||||
-> failed
|
||||
-> expired
|
||||
-> cancelled
|
||||
```
|
||||
|
||||
必须运行 Worker:
|
||||
|
||||
```bash
|
||||
npm run worker
|
||||
```
|
||||
|
||||
或 Docker Compose 中的 `zhinian-worker` 服务。
|
||||
|
||||
## 创建任务
|
||||
|
||||
```bash
|
||||
curl -X POST https://你的域名/api/v1/jobs \
|
||||
-H "Authorization: Bearer <API_KEY>" \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Idempotency-Key: demo-job-001" \
|
||||
-d '{
|
||||
"capability": "image.generate",
|
||||
"prompt": "生成一张专业产品主图",
|
||||
"width": 1440,
|
||||
"height": 2560,
|
||||
"webhookUrl": "https://example.com/zhinian/webhook"
|
||||
}'
|
||||
```
|
||||
|
||||
响应:
|
||||
|
||||
```json
|
||||
{
|
||||
"job": {
|
||||
"id": "job_xxx",
|
||||
"capability": "image.generate",
|
||||
"status": "queued",
|
||||
"outputAssetIds": []
|
||||
},
|
||||
"reused": false
|
||||
}
|
||||
```
|
||||
|
||||
### 支持的 capability
|
||||
|
||||
| capability | 说明 |
|
||||
| --- | --- |
|
||||
| `image.generate` | 图片生成 |
|
||||
| `image.inpaint` | 局部重绘 |
|
||||
| `image.upscale` | 智能超清 |
|
||||
| `video.generate` | Seedance 视频生成 |
|
||||
|
||||
## 查询任务
|
||||
|
||||
查询单个任务:
|
||||
|
||||
```bash
|
||||
curl -H "Authorization: Bearer <API_KEY>" \
|
||||
https://你的域名/api/v1/jobs/job_xxx
|
||||
```
|
||||
|
||||
查询任务列表:
|
||||
|
||||
```bash
|
||||
curl -H "Authorization: Bearer <API_KEY>" \
|
||||
"https://你的域名/api/v1/jobs?status=succeeded&limit=20"
|
||||
```
|
||||
|
||||
可用筛选:
|
||||
|
||||
- `status`:`queued`、`running`、`succeeded`、`failed`、`expired`、`cancelled`
|
||||
- `capability`:见上表
|
||||
- `limit`:`1` 到 `200`
|
||||
- `before`:ISO 时间,用于翻页
|
||||
|
||||
## 获取输出资产
|
||||
|
||||
任务成功后,`job.outputAssetIds` 会包含输出资产 ID。
|
||||
|
||||
查询资产:
|
||||
|
||||
```bash
|
||||
curl -H "Authorization: Bearer <API_KEY>" \
|
||||
https://你的域名/api/v1/assets/asset_xxx
|
||||
```
|
||||
|
||||
下载资产:
|
||||
|
||||
```bash
|
||||
curl -L \
|
||||
-H "Authorization: Bearer <API_KEY>" \
|
||||
-o result.png \
|
||||
https://你的域名/api/v1/assets/asset_xxx/download
|
||||
```
|
||||
|
||||
也可以查询当前 API client 可访问的资产列表:
|
||||
|
||||
```bash
|
||||
curl -H "Authorization: Bearer <API_KEY>" \
|
||||
https://你的域名/api/v1/assets
|
||||
```
|
||||
|
||||
## 上传或注册素材
|
||||
|
||||
上传文件:
|
||||
|
||||
```bash
|
||||
curl -X POST https://你的域名/api/v1/assets \
|
||||
-H "Authorization: Bearer <API_KEY>" \
|
||||
-F "files=@./reference.png"
|
||||
```
|
||||
|
||||
注册外部 URL:
|
||||
|
||||
```bash
|
||||
curl -X POST https://你的域名/api/v1/assets \
|
||||
-H "Authorization: Bearer <API_KEY>" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"url": "https://example.com/reference.png",
|
||||
"name": "reference.png",
|
||||
"kind": "image"
|
||||
}'
|
||||
```
|
||||
|
||||
返回的资产 ID 可放入后续任务的 `inputAssetIds`,资产 URL 可放入 `inputUrls` 或 `imageUrls`。
|
||||
|
||||
## 图片任务示例
|
||||
|
||||
图片生成:
|
||||
|
||||
```json
|
||||
{
|
||||
"capability": "image.generate",
|
||||
"prompt": "参考 @图片1 的风格,生成 9:16 旅游海报",
|
||||
"imageUrls": ["https://example.com/reference.png"],
|
||||
"width": 1440,
|
||||
"height": 2560,
|
||||
"force_single": true
|
||||
}
|
||||
```
|
||||
|
||||
智能超清:
|
||||
|
||||
```json
|
||||
{
|
||||
"capability": "image.upscale",
|
||||
"imageUrls": ["https://example.com/input.png"],
|
||||
"resolution": "4k"
|
||||
}
|
||||
```
|
||||
|
||||
局部重绘:
|
||||
|
||||
```json
|
||||
{
|
||||
"capability": "image.inpaint",
|
||||
"prompt": "把选中区域文字替换成新品上市",
|
||||
"imageUrls": [
|
||||
"https://example.com/original.png",
|
||||
"https://example.com/mask.png"
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## 视频任务示例
|
||||
|
||||
```json
|
||||
{
|
||||
"capability": "video.generate",
|
||||
"prompt": "生成一条 9:16 品牌短视频,节奏明快,适合信息流投放",
|
||||
"settings": {
|
||||
"ratio": "9:16",
|
||||
"duration": 5,
|
||||
"resolution": "720p"
|
||||
},
|
||||
"materials": [
|
||||
{
|
||||
"type": "image",
|
||||
"url": "https://example.com/product.png",
|
||||
"label": "@图片1"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
视频参数限制:
|
||||
|
||||
- `duration`:`4` 到 `15` 秒
|
||||
- `ratio`:`16:9`、`4:3`、`1:1`、`3:4`、`9:16`、`21:9`、`adaptive`
|
||||
- `resolution`:`480p`、`720p`、`1080p`
|
||||
|
||||
## 幂等
|
||||
|
||||
建议所有创建任务请求都带:
|
||||
|
||||
```http
|
||||
Idempotency-Key: <业务唯一请求ID>
|
||||
```
|
||||
|
||||
同一个 API client 使用相同 key 和相同请求体会返回已有任务;相同 key 但请求体不同会返回 `409`。
|
||||
|
||||
## Webhook
|
||||
|
||||
创建任务时传 `webhookUrl`。任务进入终态后会回调:
|
||||
|
||||
```json
|
||||
{
|
||||
"event": "generation.succeeded",
|
||||
"job": {
|
||||
"id": "job_xxx",
|
||||
"status": "succeeded",
|
||||
"outputAssetIds": ["asset_xxx"]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
如果服务端配置了:
|
||||
|
||||
```env
|
||||
ZHINIAN_WEBHOOK_SECRET=your-secret
|
||||
```
|
||||
|
||||
Webhook 请求会带:
|
||||
|
||||
```http
|
||||
X-Zhinian-Signature: sha256=<hex>
|
||||
```
|
||||
|
||||
签名内容是原始请求体 HMAC-SHA256。
|
||||
|
||||
## 错误格式
|
||||
|
||||
```json
|
||||
{
|
||||
"error": "Invalid API key."
|
||||
}
|
||||
```
|
||||
|
||||
常见状态码:
|
||||
|
||||
- `400`:请求参数错误
|
||||
- `401`:API Key 缺失或错误
|
||||
- `404`:任务或资产不存在,或不属于当前 API client
|
||||
- `409`:幂等 key 冲突
|
||||
- `500`:服务端错误或 Worker token 配置错误
|
||||
|
||||
## 最小对接流程
|
||||
|
||||
1. 运维提供域名和 API Key。
|
||||
2. 对接方调用 `GET /api/v1/capabilities` 确认能力。
|
||||
3. 对接方上传素材或注册外部 URL。
|
||||
4. 对接方调用 `POST /api/v1/jobs` 创建任务。
|
||||
5. 对接方轮询 `GET /api/v1/jobs/:id`,或等待 Webhook。
|
||||
6. 任务成功后用 `outputAssetIds` 查询并下载资产。
|
||||
162
docs/DEPLOYMENT.md
Normal file
162
docs/DEPLOYMENT.md
Normal file
@@ -0,0 +1,162 @@
|
||||
# 智念AIGC平台部署说明
|
||||
|
||||
本文面向运维部署。推荐使用 Docker Compose,同一套编排会启动 Web 服务和任务 Worker。
|
||||
|
||||
## 服务器要求
|
||||
|
||||
- Linux 服务器
|
||||
- Docker
|
||||
- Docker Compose v2(`docker compose`)或旧版 `docker-compose`
|
||||
- 可访问外网供应商接口:火山 Visual、EvoLink、Seedance、OSS
|
||||
|
||||
## 一键部署
|
||||
|
||||
```bash
|
||||
git clone <仓库地址>
|
||||
cd NianAIGC
|
||||
bash scripts/deploy.sh
|
||||
```
|
||||
|
||||
脚本会自动:
|
||||
|
||||
- 从 `.env.example` 创建 `.env.local`(如果不存在)
|
||||
- 创建 `.runtime/data`、`.runtime/uploads`、`.runtime/generated-results`
|
||||
- 构建镜像
|
||||
- 启动 `zhinian-aigc` Web 服务
|
||||
- 启动 `zhinian-worker` 任务 Worker
|
||||
- 输出容器状态
|
||||
|
||||
默认访问:
|
||||
|
||||
```text
|
||||
http://服务器IP:3000
|
||||
```
|
||||
|
||||
## 必填生产配置
|
||||
|
||||
部署前编辑 `.env.local`:
|
||||
|
||||
```env
|
||||
APP_PORT=3000
|
||||
PORT=3000
|
||||
HOSTNAME=0.0.0.0
|
||||
NEXT_PUBLIC_APP_URL=https://你的域名
|
||||
|
||||
ZHINIAN_API_KEYS=partner-a:请替换为强随机key
|
||||
ZHINIAN_INTERNAL_WORKER_TOKEN=请替换为强随机token
|
||||
ZHINIAN_WEBHOOK_SECRET=请替换为webhook签名密钥
|
||||
```
|
||||
|
||||
真实生成能力按需配置:
|
||||
|
||||
```env
|
||||
IMAGE_GENERATE_ENGINE=evolink
|
||||
IMAGE_INPAINT_ENGINE=jimeng
|
||||
|
||||
EVOLINK_API_KEY=
|
||||
|
||||
VOLCENGINE_ACCESS_KEY_ID=
|
||||
VOLCENGINE_SECRET_ACCESS_KEY=
|
||||
|
||||
SEEDANCE_API_KEY=
|
||||
|
||||
ALI_OSS_ENDPOINT=
|
||||
ALI_OSS_BUCKET=
|
||||
ALI_OSS_ACCESS_KEY_ID=
|
||||
ALI_OSS_ACCESS_KEY_SECRET=
|
||||
ALI_OSS_PUBLIC_BASE_URL=
|
||||
```
|
||||
|
||||
如果不配置真实供应商密钥,mock 配置会保留本地验收能力,但生产对接应配置真实密钥。
|
||||
|
||||
## 常用运维命令
|
||||
|
||||
```bash
|
||||
docker compose ps
|
||||
docker compose logs -f zhinian-aigc
|
||||
docker compose logs -f zhinian-worker
|
||||
docker compose restart
|
||||
docker compose down
|
||||
```
|
||||
|
||||
更新部署:
|
||||
|
||||
```bash
|
||||
git pull
|
||||
bash scripts/deploy.sh
|
||||
```
|
||||
|
||||
健康检查:
|
||||
|
||||
```bash
|
||||
curl -f http://127.0.0.1:${APP_PORT:-3000}/api/health
|
||||
```
|
||||
|
||||
OpenAPI:
|
||||
|
||||
```bash
|
||||
curl http://127.0.0.1:${APP_PORT:-3000}/api/v1/openapi.json
|
||||
```
|
||||
|
||||
## 数据持久化
|
||||
|
||||
Docker Compose 会挂载:
|
||||
|
||||
```text
|
||||
./.runtime:/app/.runtime
|
||||
```
|
||||
|
||||
本地 JSON 数据层、上传文件和生成结果都会放在 `.runtime/` 下。生产环境如果未启用 Supabase/Postgres,请定期备份该目录。
|
||||
|
||||
建议备份:
|
||||
|
||||
```bash
|
||||
tar -czf zhinian-runtime-$(date +%Y%m%d%H%M%S).tar.gz .runtime
|
||||
```
|
||||
|
||||
## 服务组成
|
||||
|
||||
- `zhinian-aigc`:Next.js Web/API 服务,默认容器端口 `3000`
|
||||
- `zhinian-worker`:后台任务 Worker,负责提交供应商任务、轮询结果、导入资产和触发 Webhook
|
||||
|
||||
注意:只启动 Web 服务时,任务会停留在 `queued` 或 `running`,必须同时运行 Worker。
|
||||
|
||||
## 反向代理建议
|
||||
|
||||
Nginx 示例:
|
||||
|
||||
```nginx
|
||||
server {
|
||||
listen 80;
|
||||
server_name your-domain.com;
|
||||
|
||||
client_max_body_size 100m;
|
||||
|
||||
location / {
|
||||
proxy_pass http://127.0.0.1:3000;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
配置反向代理后,将 `.env.local` 里的 `NEXT_PUBLIC_APP_URL` 设置成公网 HTTPS 地址。
|
||||
|
||||
## 验收清单
|
||||
|
||||
部署后执行:
|
||||
|
||||
```bash
|
||||
curl -f https://你的域名/api/health
|
||||
curl -H "Authorization: Bearer <API_KEY>" https://你的域名/api/v1/capabilities
|
||||
curl https://你的域名/api/v1/openapi.json
|
||||
```
|
||||
|
||||
确认:
|
||||
|
||||
- Web 页面可访问
|
||||
- `/api/health` 返回 `ok: true`
|
||||
- `/api/v1/capabilities` 使用 API Key 可访问
|
||||
- `zhinian-worker` 日志持续输出 `claimed=...`
|
||||
- OSS、EvoLink、火山、Seedance 密钥按业务需要配置完成
|
||||
Reference in New Issue
Block a user