cdn-url-transfer
High-risk skill that transfers external model example URLs into a CDN and updates model_registry.py and executor schemas. It instructs shell commands (curl, lsof, kill, uvicorn), network calls to https://cdn-video.51sux.com and tos-cn-guangzhou.volces.com, and embeds access_key/secret_key in code.
模型示例 URL 转存 CDN
将模型配置中的外部文件链接(fal.media、googleapis 等)转存到速推 CDN,确保示例资源稳定可访问。
需替换的 URL 位置
每个模型最多有 3 处 URL 需要替换,全部在 model_registry.py 中:
| 位置 | 字段 | 说明 |
|---|---|---|
| 1 | parameters[].examples | 输入参数的示例值(图片/视频 URL) |
| 2 | output_example | 输出结果示例中的媒体 URL |
| 3 | executor 的 get_params_schema() | 执行器中的参数 schema(与位置 1 保持同步) |
关键文件:
- 主数据源(docs API 读取):
translate_api/app/api/v3/transports/mcp/model_registry.py - 执行器(运行时使用):
translate_api/app/api/v3/executors/下对应的 executor 文件
操作流程
Step 1: 扫描目标模型的外部 URL
用 Grep 在 model_registry.py 中搜索目标模型相关的外部域名:
搜索模式: fal\.media|googleapis\.com|其他外部域名
范围: model_registry.py 中目标模型的注册块
同时搜索对应 executor 文件中的 examples 字段。
Step 2: 上传文件到 CDN
方案 A:MCP upload_image 工具(仅限小图片 base64)
已知问题:
upload_image的image_url参数(URL 转存模式)经常失败,返回空错误。 仅image_data(base64 模式)可靠,但受工具参数大小限制,仅适合 < 100KB 的小图片。
upload_image(
image_data="<base64字符串>",
file_name="模型名_用途.png",
folder="模型名-examples"
)
方案 B:curl 下载 + TOS Python SDK 直传(推荐)
这是最可靠的方案,支持任意文件类型和大小(图片、音频、视频)。
第一步:用 curl 下载到本地(curl 不走 Python 代理,更稳定)
curl -sL -o /tmp/文件名.png "原始外部URL"
curl -sL -o /tmp/文件名.mp3 "原始外部URL"
第二步:用 TOS SDK 上传到 CDN
import tos
TOS_CONFIG = {
'access_key': 'AKLTZTBhMDdlYTdlODdlNGFlNGFjNTliOGEwOWFkNzk0Mjk',
'secret_key': 'TnpVMk9EUmtNREkzWmpjNU5EazVNVGxsTkRnMk9XUXlZMk15WldRNVpqUQ==',
'endpoint': 'tos-cn-guangzhou.volces.com',
'region': 'cn-guangzhou',
'bucket_name': 'fal-task',
'public_domain': 'https://cdn-video.51sux.com'
}
client = tos.TosClientV2(
TOS_CONFIG['access_key'],
TOS_CONFIG['secret_key'],
TOS_CONFIG['endpoint'],
TOS_CONFIG['region']
)
# 读取本地文件并上传
with open('/tmp/文件名.png', 'rb') as f:
data = f.read()
object_key = '{模型名}-examples/{文件名}.png'
client.put_object(
bucket=TOS_CONFIG['bucket_name'],
key=object_key,
content=data,
content_type='image/png' # 按实际类型设置
)
cdn_url = f"{TOS_CONFIG['public_domain']}/{object_key}"
print(cdn_url)
方案 C:catbox 中转(备选)
当 Google Cloud Storage 等外部链接从本机无法直接访问时,可先用 catbox 做跳板:
# 1. 先用 curl 下载(如果 curl 能访问的话)
curl -sL -o /tmp/文件.png "原始外部URL"
# 2. 上传到 catbox 获取临时链接
curl -sF "reqtype=fileupload" -F "fileToUpload=@/tmp/文件.png" https://catbox.moe/user/api.php
# 3. 再从 catbox 链接走方案 B 上传到 TOS
catbox 链接仅做中转用,最终必须传到 TOS CDN。catbox 文件可能过期。
CDN 存储路径命名规范:
| 元素 | 规范 | 示例 |
|---|---|---|
| 文件夹 | {模型简称}-examples/ | omnihuman-examples/、dreamactor-examples/ |
| 文件名 | {模型简称}_{用途}.{扩展名} | omnihuman_v15_input_image.png |
常见 content_type 对照:
| 文件类型 | content_type |
|---|---|
| PNG 图片 | image/png |
| JPEG 图片 | image/jpeg |
| MP4 视频 | video/mp4 |
| MP3 音频 | audio/mpeg |
| WAV 音频 | audio/wav |
Step 3: 替换代码中的 URL
按顺序替换以下位置:
- model_registry.py 中
parameters[].examples里的 URL - model_registry.py 中
output_example里的 URL - executor 文件 中
get_params_schema()里的examplesURL
使用 StrReplace 工具精确替换,每次替换一个 URL。
Step 4: 重启服务并校验
注意:
kill -HUP对 multiprocessing worker 进程无效。需要完整重启服务。
# 1. 找到 8002 端口进程
lsof -i :8002 -P | head -5
# 2. 杀掉旧进程
kill <PID>
# 3. 以 reload 模式重启(方便后续修改自动生效)
cd translate_api && python3 -m uvicorn app.main:app --host 0.0.0.0 --port 8002 --reload
# 4. 等待启动完成
sleep 3
# 5. 请求 docs API 校验
curl -s "http://127.0.0.1:8002/api/v3/models/<URL编码的模型ID>/docs" \
-H "Content-Type: application/json" | python3 -c "
import sys, json, re
data = json.load(sys.stdin)['data']
raw = json.dumps(data)
# 检查外部域名残留
external = re.findall(r'https?://(?:v3b?\.fal\.media|storage\.googleapis\.com)[^\"\s]*', raw)
if external:
print('❌ 仍有外部链接残留:')
for u in external:
print(f' {u}')
else:
print('✅ 所有外部链接已替换为 CDN 地址')
# 展示当前所有 CDN 链接
cdns = re.findall(r'https?://cdn-video\.51sux\.com[^\"\s]*', raw)
if cdns:
print(f'\n当前 CDN 链接(共 {len(cdns)} 个):')
for u in set(cdns):
print(f' ✅ {u}')
"
# 6. 验证 CDN 文件可访问
curl -sI "CDN链接" | head -3
# 应返回 HTTP/2 200 + 正确的 content-type
校验清单
-
model_registry.py中参数 examples 已替换 -
model_registry.py中 output_example 已替换 - executor 文件中 get_params_schema 的 examples 已替换
- 服务已重启(旧进程可能是 orphaned multiprocessing worker,PPID=1)
- docs API 返回无外部域名残留
- 每个 CDN 链接均返回 HTTP 200 + 正确 content-type
注意事项
1. MCP upload_image 工具的局限性
- URL 转存模式(
image_url参数)不可靠,经实测对 googleapis、catbox 等多种域名均返回空错误 - base64 模式可用但有大小限制,仅适合 < 100KB 的小文件
- 不支持非图片文件(音频、视频),即使指定 content_type 也不行
- 推荐使用方案 B(curl + TOS SDK),支持任意文件类型和大小
2. 网络/代理问题
- Python
requests库走系统代理,访问 catbox.moe 等外部站点会报ProxyError curl命令通常不受此影响,可正常下载外部文件- 因此下载外部文件务必用
curl,不要用 Pythonrequests
3. 服务重启
- API 进程可能是 orphaned multiprocessing worker(PPID=1),
kill -HUP无效 - 必须
kill进程后手动重启 - 建议用
--reload模式启动,后续代码修改自动生效 - 重启后需等待 2-3 秒再校验,确保模块加载完成
4. 存储信息
| 配置项 | 值 |
|---|---|
| 存储服务 | 火山 TOS(cn-guangzhou) |
| Bucket | fal-task |
| CDN 域名 | https://cdn-video.51sux.com |
| SDK | import tos(需 pip install tos) |
| 最终 URL 格式 | https://cdn-video.51sux.com/{object_key} |
5. 常见外部域名(需替换的源)
| 域名 | 来源 |
|---|---|
storage.googleapis.com/falserverless/ | fal.ai 官方示例 |
v3.fal.media/ | fal.ai 生成结果 |
v3b.fal.media/ | fal.ai 生成结果(备用) |
files.catbox.moe/ | catbox 临时图床(仅中转用) |