如何用 API 与 Webhook 批量把图表图片转换成 VSDX

一张图表截图是手工任务,五百张遗留架构图就是迁移项目。批量转换不能只写一个文件循环,还需要异步任务、持久化任务 ID、受控并发、下载验证,以及防止同一图片被重复计费的记录。

本文以 LayerBack 转换 API为例。它接收 PNG、JPEG、WebP,一次转换生成 VSDX、PPTX、draw.io、SVG、结构化 IR 和预览图。

API 生命周期

流程分三步:

  1. 把原始图像字节发给 POST /api/v1/convert,取得 job_id
  2. 轮询 GET /api/v1/jobs/{job_id},或者提供完成 Webhook;
  3. /download?format=... 下载需要的文件。

任务状态依次为 queued → running → succeeded,失败则进入 failed。转换通常需要 30~60 秒,不适合长时间占用普通同步请求。

Settings → API Keys 创建密钥,并存入环境变量:

bash 复制代码
export LAYERBACK_API_KEY="replace-with-your-key"

不要把密钥提交到 Git、写进前端 JavaScript、留在截图里,或直接硬编码在脚本中。

提交一张图片

bash 复制代码
curl -X POST https://layerback.com/api/v1/convert \
  -H "x-api-key: $LAYERBACK_API_KEY" \
  -H "Content-Type: application/octet-stream" \
  --data-binary @diagram.png

响应中包含 job_id。拿到后立即保存源文件路径、SHA-256、任务 ID 与提交时间。如果提交已经成功,但进程在记录 ID 前崩溃,自动重跑可能导致同一图片再次转换和计费。

查询状态并安全下载

bash 复制代码
curl https://layerback.com/api/v1/jobs/$JOB_ID \
  -H "x-api-key: $LAYERBACK_API_KEY"

成功后,下载时要允许跟随重定向:

bash 复制代码
curl -L \
  "https://layerback.com/api/v1/jobs/$JOB_ID/download?format=vsdx" \
  -H "x-api-key: $LAYERBACK_API_KEY" \
  -o diagram.vsdx

接口可能跳转到短时有效的对象存储地址,所以 -L 不能省。下载完成后,确认文件非空并能作为 ZIP/OOXML 包打开,再把该行标记为完成。

一个便于恢复的 Python 批处理

下面的模式优先保证可恢复性,而不是追求最大吞吐:顺序提交、写入 JSON Lines 清单、固定间隔轮询并下载 VSDX。

python 复制代码
import hashlib, json, os, time
from pathlib import Path
import requests

BASE = "https://layerback.com/api/v1"
HEADERS = {"x-api-key": os.environ["LAYERBACK_API_KEY"]}
src_dir, out_dir = Path("legacy-diagrams"), Path("converted-vsdx")
out_dir.mkdir(exist_ok=True)

def digest(path):
    return hashlib.sha256(path.read_bytes()).hexdigest()

def log(event):
    with open("conversion-manifest.jsonl", "a", encoding="utf-8") as f:
        f.write(json.dumps(event, ensure_ascii=False) + "\n")

for source in sorted(src_dir.iterdir()):
    if source.suffix.lower() not in {".png", ".jpg", ".jpeg", ".webp"}:
        continue
    response = requests.post(
        f"{BASE}/convert",
        headers={**HEADERS, "Content-Type": "application/octet-stream"},
        data=source.read_bytes(), timeout=90)
    response.raise_for_status()
    job_id = response.json()["job_id"]
    log({"source": str(source), "sha256": digest(source),
         "job_id": job_id, "state": "submitted"})

    while True:
        status = requests.get(f"{BASE}/jobs/{job_id}",
                              headers=HEADERS, timeout=30).json()
        if status["status"] in {"succeeded", "failed"}:
            break
        time.sleep(5)
    if status["status"] == "failed":
        log({"job_id": job_id, "state": "failed",
             "error": status.get("error")})
        continue

    artifact = requests.get(
        f"{BASE}/jobs/{job_id}/download?format=vsdx",
        headers=HEADERS, timeout=90, allow_redirects=True)
    artifact.raise_for_status()
    target = out_dir / f"{source.stem}.vsdx"
    target.write_bytes(artifact.content)
    log({"job_id": job_id, "state": "downloaded",
         "target": str(target), "bytes": target.stat().st_size})

用于生产时,应在启动时读取清单,跳过已经处于 submittedsucceededdownloaded 的哈希。先证明恢复流程可靠,再增加有上限的工作池。

大队列使用 Webhook

bash 复制代码
curl -X POST \
  "https://layerback.com/api/v1/convert?callback_url=https://example.com/hooks/layerback" \
  -H "x-api-key: $LAYERBACK_API_KEY" \
  -H "Content-Type: application/octet-stream" \
  --data-binary @diagram.png

回调包含任务 ID、状态、耗时、错误和格式列表。当前 API 文档说明会尝试投递两次。应把 Webhook 当成通知,对于重要结果,再调用任务状态接口确认后下载。

接收端必须以 job_id 为键实现幂等。同一通知重复到达或晚到,都不能触发一次新的转换。

生产检查清单

  • 只允许 20 MB 以下的 PNG、JPEG 和 WebP;
  • 当前默认上限为每账号每小时 20 次转换;
  • 分别处理 402、413、415、429:余额、大小、格式和速率限制;
  • 轮询前持久化源文件哈希与任务 ID;
  • 限制并发,不要一次启动整个文件库;
  • 网络读取可以重试,但结果未知的转换不能盲目重新提交;
  • 文件至少保留 72 小时,应尽快下载;
  • 删除源图前,验证 VSDX 和 PPTX 包;
  • 在迁移清单中记录失败与人工复核备注。

一次转换消耗 10 积分并包含所有格式,因此不要为了不同格式重复提交同一图片。先用 10 张有代表性的图测试并统计清理时间,再沿用同一套清单与验证规则扩大规模。

相关推荐
2601_962100542 小时前
python包和模块的内容整理
python·模块·导入·虚拟环境·
二进制漫游记2 小时前
FastAPI项目集成 Qdrant向量数据库+阿里云Embedding完整实战(工具封装+业务调用)
数据库·python·阿里云·embedding
-今昭-3 小时前
《V2V 迁移实战:将 VMware 虚拟机转为 OpenStack 可用 Glance qcow2 镜像》
开发语言·python
2601_962381583 小时前
【转】Python渗透测试工具:sqlmap
python·渗透测试·sql注入·sqlmap·数据库安全
朗宇芯工控4 小时前
注塑机械手自动化上下料原理、流程与应用优势
机器人·自动化·制造·工业·运动控制系统
用户3721574261354 小时前
如何使用 Python 从 Word 文档中提取图片
python
白山编程大哥5 小时前
Java 集合算法:从排序、查找到底层原理的实战指南
java·python·算法
2601_962304916 小时前
把出片接进自动化流水线:2026 年批量 AI 视频生成工具的脚本契约与同类项目对照
运维·人工智能·自动化
昭昭日月明6 小时前
RAGFlow 入门,不用从零造轮子
python·ai编程