Files
xiaoxia-saas/tests/render_compare/create_test_asset.py
T
CI Bot 0347958d75
CI/CD Pipeline / Validate Code Quality And Tests (pull_request) Successful in 33s
CI/CD Pipeline / Unit Tests (pull_request) Successful in 1m5s
CI/CD Pipeline / Frontend Lint (pull_request) Successful in 1m14s
CI/CD Pipeline / Build & Push Staging (Watchtower auto-deploy) (pull_request) Has been skipped
CI/CD Pipeline / Build Production Runtime Images (pull_request) Has been skipped
CI/CD Pipeline / Staging E2E Tests (pull_request) Has been skipped
CI/CD Pipeline / Deploy Production (pull_request) Has been skipped
CI/CD Pipeline / Staging API Integration Tests (pull_request) Has been skipped
CI/CD Pipeline / Production Browser E2E (pull_request) Has been skipped
CI/CD Pipeline / Integration Tests (pull_request) Successful in 1m16s
fix: 修复flake8 F811/F541问题
2026-07-14 09:24:50 +08:00

256 lines
7.0 KiB
Python
Executable File
Raw 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.
#!/usr/bin/env python3
"""
自动化测试用:一键创建 ready 状态的视频素材。
跳过转码和上传流程,直接指定 storage_key 创建可用素材,
供渲染对比测试等场景快速生成测试素材。
用法示例:
python create_test_asset.py \
--base-url http://localhost:8000 \
--token xxx \
--project-id proj_xxx \
--name "测试素材-30s" \
--storage-key "assets/test/video.mp4" \
--duration 30 \
--file-size 10485760
"""
import argparse
import json
import os
import sys
import urllib.error
import urllib.request
def parse_args():
parser = argparse.ArgumentParser(description="创建 ready 状态的测试素材(跳过转码上传)")
parser.add_argument(
"--base-url",
default=os.environ.get("API_BASE_URL", "http://localhost:8000"),
help="API 地址,默认 http://localhost:8000(或环境变量 API_BASE_URL",
)
parser.add_argument(
"--token",
default=os.environ.get("API_TOKEN", ""),
help="登录 token(或环境变量 API_TOKEN",
)
parser.add_argument(
"--project-id",
required=True,
help="项目 ID",
)
parser.add_argument(
"--name",
required=True,
help="素材名称",
)
parser.add_argument(
"--storage-key",
required=True,
help="OSS storage_key(文件必须已存在于 OSS",
)
parser.add_argument(
"--duration",
type=float,
default=30.0,
help="视频时长(秒),默认 30",
)
parser.add_argument(
"--width",
type=int,
default=1280,
help="视频宽度,默认 1280",
)
parser.add_argument(
"--height",
type=int,
default=720,
help="视频高度,默认 720",
)
parser.add_argument(
"--fps",
type=float,
default=25.0,
help="帧率,默认 25",
)
parser.add_argument(
"--mime-type",
default="video/mp4",
help="MIME 类型,默认 video/mp4",
)
parser.add_argument(
"--file-size",
type=int,
default=0,
help="文件大小(字节),默认 0",
)
parser.add_argument(
"--codec",
default=None,
help="视频编码,可选",
)
parser.add_argument(
"--kind",
default="video",
choices=["video", "voice", "image"],
help="素材库类型,默认 video",
)
return parser.parse_args()
def api_request(base_url: str, token: str, method: str, path: str, body: dict | None = None) -> dict:
"""发送 API 请求,返回 JSON 响应。"""
url = f"{base_url.rstrip('/')}{path}"
data = json.dumps(body).encode("utf-8") if body else None
headers = {
"Content-Type": "application/json",
}
if token:
headers["Authorization"] = f"Bearer {token}"
req = urllib.request.Request(url, data=data, method=method, headers=headers)
try:
with urllib.request.urlopen(req) as resp:
resp_body = resp.read().decode("utf-8")
return json.loads(resp_body) if resp_body else {}
except urllib.error.HTTPError as e:
error_body = e.read().decode("utf-8", errors="replace")
print(f"[ERROR] API 请求失败: {method} {url}", file=sys.stderr)
print(f" HTTP {e.code}: {e.reason}", file=sys.stderr)
print(f" 响应内容: {error_body}", file=sys.stderr)
sys.exit(1)
except urllib.error.URLError as e:
print(f"[ERROR] 网络错误: {method} {url}", file=sys.stderr)
print(f" 原因: {e.reason}", file=sys.stderr)
sys.exit(1)
def ensure_default_library(base_url: str, token: str, project_id: str, kind: str) -> str:
"""确保项目有默认素材库,返回 library_id。"""
print(f"[1/2] 确保默认 {kind} 素材库存在...")
result = api_request(
base_url,
token,
"POST",
"/api/v1/asset-libraries/ensure-default",
body={"project_id": project_id, "kind": kind},
)
library_id = result.get("id")
library_name = result.get("name")
print(f" 素材库: {library_name} (id: {library_id})")
return library_id
def create_asset(
base_url: str,
token: str,
project_id: str,
library_id: str,
name: str,
storage_key: str,
mime_type: str,
file_size: int,
duration: float,
width: int,
height: int,
fps: float,
codec: str | None,
) -> dict:
"""创建 ready 状态的素材。"""
print("[2/2] 创建 ready 状态素材...")
body = {
"project_id": project_id,
"library_id": library_id,
"name": name,
"storage_key": storage_key,
"mime_type": mime_type,
"file_size": file_size,
"duration": duration,
"width": width,
"height": height,
"fps": fps,
"status": "ready",
"classification_status": "pending",
"metadata": {},
}
if codec:
body["codec"] = codec
result = api_request(
base_url,
token,
"POST",
"/api/v1/assets",
body=body,
)
return result
def main():
args = parse_args()
if not args.token:
print("[ERROR] 请通过 --token 参数或 API_TOKEN 环境变量提供登录 token", file=sys.stderr)
sys.exit(1)
print("=" * 60)
print("创建测试素材工具")
print("=" * 60)
print(f" API 地址: {args.base_url}")
print(f" 项目 ID: {args.project_id}")
print(f" 素材名称: {args.name}")
print(f" storage_key: {args.storage_key}")
print(f" 分辨率: {args.width}x{args.height} @ {args.fps}fps")
print(f" 时长: {args.duration}s")
print(f" 文件大小: {args.file_size} bytes")
print("=" * 60)
print()
# Step 1: 确保默认素材库存在
library_id = ensure_default_library(args.base_url, args.token, args.project_id, args.kind)
# Step 2: 创建素材
asset = create_asset(
base_url=args.base_url,
token=args.token,
project_id=args.project_id,
library_id=library_id,
name=args.name,
storage_key=args.storage_key,
mime_type=args.mime_type,
file_size=args.file_size,
duration=args.duration,
width=args.width,
height=args.height,
fps=args.fps,
codec=args.codec,
)
asset_id = asset.get("id")
print()
print("=" * 60)
print("✓ 素材创建成功!")
print("=" * 60)
print(f" asset_id: {asset_id}")
print(f" 状态: {asset.get('status')}")
print(f" 素材库 ID: {asset.get('library_id')}")
print(f" 文件 URL: {asset.get('file_url', 'N/A')}")
print("=" * 60)
print()
print("调用示例:")
print(f" export ASSET_ID={asset_id}")
print(" # 在生成任务中使用:")
print(" # --asset-id $ASSET_ID")
print()
# 输出 asset_id 到 stdout(方便脚本捕获)
print(asset_id)
if __name__ == "__main__":
main()