- driver.sh: PYTHONPATH-based, no-install CLI wrapper with auth diagnostics - exit codes: 0 ok / 1 env / 2 auth-expired / 3 cookie missing - verified live 2026-08-15: quota, list, status, formats, download - text (quota-consuming) documented as request-layer verified only
128 lines
4.3 KiB
Bash
Executable File
128 lines
4.3 KiB
Bash
Executable File
#!/usr/bin/env bash
|
||
# 腾讯混元3D Python 客户端 driver
|
||
# 从源码直接运行(PYTHONPATH 指向仓库根),无需 pip install。
|
||
# 所有命令都是对 `python3 -m hunyuan3dweb.cli` 的薄封装,加上统一的
|
||
# 认证/错误诊断(401 分类、退出码),方便 agent 自动化判断。
|
||
#
|
||
# 退出码: 0=成功 1=环境/其他错误 2=认证失败(需重新登录) 3=cookie 文件缺失
|
||
set -uo pipefail
|
||
|
||
# 仓库根 = driver 上三级(.claude/skills/run-hunyuan3dweb/driver.sh)
|
||
UNIT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../.." && pwd)"
|
||
export PYTHONPATH="${PYTHONPATH:+$PYTHONPATH:}$UNIT_DIR"
|
||
|
||
# cookie 可通过环境变量覆盖(多账号场景)
|
||
COOKIE_FILE="${HUNYUAN3D_COOKIES:-$HOME/.config/hunyuan3dweb/cookies.txt}"
|
||
|
||
need_cookie() {
|
||
if [[ ! -f "$COOKIE_FILE" || ! -s "$COOKIE_FILE" ]]; then
|
||
echo "ERR3: cookie 文件缺失或为空: $COOKIE_FILE" >&2
|
||
echo " 首次使用需人工登录: 在真实终端运行下面的命令,按提示输邮箱+验证码" >&2
|
||
echo " PYTHONPATH=$UNIT_DIR python3 -m hunyuan3dweb.browser.login" >&2
|
||
exit 3
|
||
fi
|
||
}
|
||
|
||
# 从 CLI 输出中诊断认证类错误(ec=2 表示凭证问题,不是代码问题)
|
||
diagnose() {
|
||
local out="$1"
|
||
if grep -q '"code":"20001"' <<<"$out"; then
|
||
echo "AUTH_EXPIRED: token 无效/过期 → 需人工重新登录(见下)" >&2
|
||
echo " PYTHONPATH=$UNIT_DIR python3 -m hunyuan3dweb.browser.login" >&2
|
||
return 2
|
||
elif grep -q '"code":"999"' <<<"$out"; then
|
||
echo "AUTH_NO_COOKIE: 服务端说 cookie 里没有用户 → 检查 cookie 内容或重新登录" >&2
|
||
return 2
|
||
elif grep -qE '400 Client Error' <<<"$out"; then
|
||
echo "BAD_REQUEST: HTTP 400(常见于 creationsId 不存在/无效)" >&2
|
||
return 1
|
||
fi
|
||
echo "--- 原始输出尾部 ---" >&2
|
||
tail -5 <<<"$out" >&2
|
||
return 1
|
||
}
|
||
|
||
cmd_verify() {
|
||
# 1) 依赖检查
|
||
python3 -c "import requests" 2>/dev/null \
|
||
|| { echo "ERR1: 缺少 requests,运行 pip install requests" >&2; exit 1; }
|
||
# 2) 离线签名自检(不依赖网络/登录)
|
||
python3 - <<'PY'
|
||
import os, sys
|
||
sys.path.insert(0, os.environ["PYTHONPATH"])
|
||
from hunyuan3dweb.sign import derive_key, C, sign
|
||
k = derive_key(C)
|
||
assert k == "Hf6d6KFB3D", f"派生密钥不符: {k!r}"
|
||
s = sign({"a": 1})
|
||
assert len(s["sign"]) == 64 and s["sign"].isalnum(), "签名格式异常"
|
||
print(f"sign OK: 密钥={k} 签名={s['sign'][:12]}...")
|
||
PY
|
||
# 3) 在线配额(认证能力检查)
|
||
cmd_quota
|
||
}
|
||
|
||
cmd_quota() {
|
||
need_cookie
|
||
local out
|
||
out="$(python3 -m hunyuan3dweb.cli quota 2>&1)" || { diagnose "$out"; exit $?; }
|
||
echo "$out"
|
||
}
|
||
|
||
cmd_list() {
|
||
need_cookie
|
||
local out
|
||
out="$(python3 -m hunyuan3dweb.cli list 2>&1)" || { diagnose "$out"; exit $?; }
|
||
echo "$out"
|
||
}
|
||
|
||
cmd_status() {
|
||
need_cookie
|
||
local out
|
||
out="$(python3 -m hunyuan3dweb.cli status "$1" 2>&1)" || { diagnose "$out"; exit $?; }
|
||
echo "$out"
|
||
}
|
||
|
||
# text 在本容器内未跑过完整成功路径(消耗配额,用户当时只授权只读验证)。
|
||
# 其余命令均已实测:quota/list/status/formats/download(2026-08-15)。
|
||
cmd_text() {
|
||
need_cookie
|
||
python3 -m hunyuan3dweb.cli text "$1"
|
||
}
|
||
|
||
cmd_formats() {
|
||
need_cookie
|
||
python3 -m hunyuan3dweb.cli formats "$1"
|
||
}
|
||
|
||
cmd_download() {
|
||
need_cookie
|
||
python3 -m hunyuan3dweb.cli download "$@" # 下载到 CWD
|
||
}
|
||
|
||
usage() {
|
||
cat <<'USAGE'
|
||
用法: driver.sh <command> [args]
|
||
|
||
verify 环境+离线签名+配额 三重自检(最快确认能用)
|
||
quota 查询配额(remain/total)
|
||
list 作品列表 JSON
|
||
status <creationsId> 生成状态 JSON
|
||
text "<prompt>" 文生 3D(提交任务,消耗配额)
|
||
formats <creationsId> 列出该创作的可用下载格式
|
||
download <creationsId> [--format glb] [--output PATH] [--converted]
|
||
|
||
环境: HUNYUAN3D_COOKIES=custom/path 覆盖默认 cookie 文件
|
||
退出码: 0 成功 | 1 环境/其他 | 2 认证失败(需重登)| 3 cookie 缺失
|
||
USAGE
|
||
}
|
||
|
||
case "${1:-}" in
|
||
verify) shift; cmd_verify ;;
|
||
quota) shift; cmd_quota ;;
|
||
list) shift; cmd_list ;;
|
||
status) shift; cmd_status "${1:?缺少 creationsId}";;
|
||
text) shift; cmd_text "${1:?缺少 prompt}";;
|
||
formats) shift; cmd_formats "${1:?缺少 creationsId}";;
|
||
download) shift; cmd_download "$@" ;;
|
||
*) usage; exit ${1:+1};;
|
||
esac |