
Wan2.7-T2V 的 API 调用
html
curl --location 'https://dashscope.aliyuncs.com/api/v1/services/aigc/video-generation/video-synthesis' \
-H 'X-DashScope-Async: enable' \
-H "Authorization: Bearer $DASHSCOPE_API_KEY" \
-H 'Content-Type: application/json' \
-d '{
"model": "wan2.7-t2v",
"input": {
"prompt": "一段紧张刺激的侦探追查故事,展现电影级叙事能力。第1个镜头[0-3秒] 全景:雨夜的纽约街头,霓虹灯闪烁,一位身穿黑色风衣的侦探快步行走。 第2个镜头[3-6秒] 中景:侦探进入一栋老旧建筑,雨水打湿了他的外套,门在他身后缓缓关闭。 第3个镜头[6-9秒] 特写:侦探的眼神坚毅专注,远处传来警笛声,他微微皱眉思考。 第4个镜头[9-12秒] 中景:侦探在昏暗走廊中小心前行,手电筒照亮前方。 第5个镜头[12-15秒] 特写:侦探发现关键线索,脸上露出恍然大悟的表情。"
},
"parameters": {
"resolution": "720P",
"ratio": "16:9",
"prompt_extend": true,
"watermark": true,
"duration": 15
}
}'
python代码样例:
python
逐行说明解释代码含义和用法
import os
import time
import uuid
import requests
from dotenv import load_dotenv
# 加载密钥,同目录 .env 文件 DASHSCOPE_API_KEY=sk-xxx
load_dotenv()
API_KEY = os.getenv("DASHSCOPE_API_KEY")
BASE_URL = "https://dashscope.aliyuncs.com/api/v1"
def submit_task(prompt: str):
headers = {
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json",
"X-DashScope-Async": "enable"
}
payload = {
"model": "wan2.7-t2v",
"input": {
"prompt": prompt
},
"parameters": {
"resolution": "720P",
"ratio": "16:9",
"prompt_extend": True,
"watermark": True,
"duration": 5
}
}
resp = requests.post(
f"{BASE_URL}/services/aigc/video-generation/video-synthesis",
headers=headers,
json=payload,
timeout=120
)
resp.raise_for_status()
return resp.json()["output"]["task_id"]
def wait_task(task_id: str, poll_interval=6, max_wait=300):
headers = {"Authorization": f"Bearer {API_KEY}"}
start = time.time()
while time.time() - start < max_wait:
r = requests.get(f"{BASE_URL}/tasks/{task_id}", headers=headers, timeout=60)
r.raise_for_status()
data = r.json()
status = data["output"]["task_status"]
print(f"task status: {status}")
if status == "SUCCEEDED":
return data["output"]["video_url"]
if status in ("FAILED", "CANCELED"):
msg = data.get("output", {}).get("message", "unknown error")
raise RuntimeError(f"任务失败: {msg}")
time.sleep(poll_interval)
raise TimeoutError("任务等待超时")
def download_mp4(url: str, save_dir="./out"):
os.makedirs(save_dir, exist_ok=True)
fn = f"{uuid.uuid4()}.mp4"
out_path = os.path.join(save_dir, fn)
print(f"开始下载视频: {url} -> {out_path}")
r = requests.get(url, stream=True, timeout=300)
r.raise_for_status()
with open(out_path, "wb") as f:
for chunk in r.iter_content(chunk_size=8192):
f.write(chunk)
return out_path
if __name__ == "__main__":
if not API_KEY:
raise Exception("请配置 .env 文件 DASHSCOPE_API_KEY")
test_prompt = "海边日落,海浪轻轻拍打沙滩,电影级画面"
print("提交生成任务...")
tid = submit_task(test_prompt)
print(f"task_id: {tid}")
remote_video_url = wait_task(tid)
print(f"云端视频地址: {remote_video_url}")
local_file = download_mp4(remote_video_url)
print(f"✅完成,本地文件:{local_file}")
逐行详细解释代码含义、作用、用法
依赖安装:
bash
pip install requests python-dotenv
项目目录新建 .env 文件,内容:
env
DASHSCOPE_API_KEY=sk-你的dashscope密钥
python
import os
导入操作系统内置模块
用途:读取环境变量、创建文件夹、拼接文件路径,文件系统相关操作。
python
import time
导入时间模块
用途:获取时间戳、sleep休眠,用于轮询任务、超时控制。
python
import uuid
导入唯一ID生成工具
用途:生成随机不重复文件名,避免下载视频时重名覆盖旧文件。
python
import requests
HTTP网络请求库,Python最常用http客户端
用途:POST提交视频任务、GET查询任务状态、GET下载视频文件。
python
from dotenv import load_dotenv
从
python‑dotenv第三方库导入加载.env文件函数用途:读取项目目录下
.env文件,把里面配置项加载到程序环境变量,密钥不要硬编码写代码里。
python
# 加载密钥,同目录 .env 文件 DASHSCOPE_API_KEY=sk-xxx
load_dotenv()
执行加载:读取当前脚本所在目录下的
.env文件,将文件内键值对注入到程序环境变量。注意:
.env和py脚本放在同一个文件夹才会生效。
python
API_KEY = os.getenv("DASHSCOPE_API_KEY")
os.getenv("键名")读取环境变量;优先读取.env里的值,如果系统全局环境变量有同名,会优先系统环境变量。API_KEY:阿里云Dashscope鉴权密钥,后面所有http请求头部要用。
python
BASE_URL = "https://dashscope.aliyuncs.com/api/v1"
Dashscope接口根域名地址。
后面所有接口拼接这个根地址,便于统一维护,修改域名只改一处。
python
def submit_task(prompt: str):
定义函数
submit_task,接收字符串参数prompt(视频生成提示词)。功能:提交Wan2.7‑T2V异步视频生成任务,返回task_id任务编号。
python
headers = {
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json",
"X-DashScope-Async": "enable"
}
HTTP请求头字典
Authorization: Bearer {API_KEY}:身份鉴权,阿里云识别调用者账号;Content-Type: application/json:请求体是JSON格式;X‑DashScope‑Async: enable:强制开启异步模式。
⚠️文生视频耗时几十秒,不能同步阻塞返回视频;开启后接口只返回task_id,必须轮询查询结果。
python
payload = {
"model": "wan2.7-t2v",
"input": {
"prompt": prompt
},
"parameters": {
"resolution": "720P",
"ratio": "16:9",
"prompt_extend": True,
"watermark": True,
"duration": 5
}
}
payload:POST请求发送给接口的JSON请求体
model:指定模型名称,固定wan2.7‑t2v,写错会报错;input.prompt:传入函数参数prompt,描述想要生成的视频画面;parameters生成参数:resolution:"720P":视频分辨率;ratio:"16:9":画面宽高比;prompt_extend:True:开启AI自动扩展优化提示词;watermark:True:添加官方水印;duration:5:视频时长5秒。
python
resp = requests.post(
f"{BASE_URL}/services/aigc/video-generation/video-synthesis",
headers=headers,
json=payload,
timeout=120
)
发送POST请求,提交视频生成任务
- url:拼接根地址 + 文生视频提交接口路径;
headers=headers:带上鉴权等请求头;json=payload:requests自动把字典转为JSON字符串放到请求body;timeout=120:http超时120秒,连接长时间无响应直接抛异常,防止程序卡死。
python
resp.raise_for_status()
requests内置方法:如果HTTP状态码4xx/5xx(401密钥错误、400参数错误、500服务错误),直接抛出异常终止 。
不写这句的话,出错接口返回错误json,但是程序不会报错,继续往下执行,导致后续取key时报KeyError。
python
return resp.json()["output"]["task_id"]
resp.json():把http返回文本解析成python字典;
取出
output.task_id任务ID,返回给调用方;异步模式提交成功,只返回task_id,此时还没有视频。
python
def wait_task(task_id: str, poll_interval=6, max_wait=300):
定义轮询等待任务函数
参数:
task_id:submit_task返回的任务编号;poll_interval=6:默认每6秒查询一次任务状态;max_wait=300:最大总等待时间300秒(5分钟),超过直接报超时。
功能:循环查询任务进度,成功返回云端视频url;失败/超时抛出异常。
python
headers = {"Authorization": f"Bearer {API_KEY}"}
查询接口同样需要鉴权头,只需要Authorization字段。
python
start = time.time()
获取当前时间戳(秒),记录任务开始等待时刻,用于做最大超时判断。
python
while time.time() - start < max_wait:
while循环条件:当前时间 − 开始时间 < 最大等待秒数。
总等待时间没超过上限,继续轮询;超过就跳出循环报超时。
python
r = requests.get(f"{BASE_URL}/tasks/{task_id}", headers=headers, timeout=60)
GET请求,调用Dashscope任务查询接口,传入task_id,查询当前任务状态。
python
r.raise_for_status()
查询接口HTTP出错(网络、鉴权)直接抛异常。
python
data = r.json()
将返回报文解析为字典。
python
status = data["output"]["task_status"]
取出任务状态字段,状态枚举:
PENDING排队、RUNNING生成中、SUCCEEDED成功、FAILED失败、CANCELED已取消。
python
print(f"task status: {status}")
控制台打印状态,方便调试看进度。
python
if status == "SUCCEEDED":
return data["output"]["video_url"]
如果任务成功,取出云端OSS视频临时下载链接,函数return返回url,结束函数。
python
if status in ("FAILED", "CANCELED"):
msg = data.get("output", {}).get("message", "unknown error")
raise RuntimeError(f"任务失败: {msg}")
任务失败或者被取消:读取接口返回的错误message;抛出运行时异常,上层代码捕获即可知道失败原因。
.get()写法:防止output/message字段不存在触发KeyError。
python
time.sleep(poll_interval)
休眠poll_interval秒,避免高频请求API触发限流。
python
raise TimeoutError("任务等待超时")
while循环结束(总等待超过max_wait),抛出超时异常。
python
def download_mp4(url: str, save_dir="./out"):
视频下载函数
参数:
- url:云端视频http链接;
save_dir="./out":默认保存文件夹为当前目录下out文件夹。
返回值:视频本地完整路径。
python
os.makedirs(save_dir, exist_ok=True)
创建保存文件夹。
exist_ok=True:文件夹已经存在,不会抛出异常,不会重复报错。
python
fn = f"{uuid.uuid4()}.mp4"
uuid.uuid4()生成全球唯一随机字符串作为文件名,避免不同视频重名覆盖。
python
out_path = os.path.join(save_dir, fn)
os.path.join跨平台拼接路径(Windows反斜杠、Linux斜杠自动适配),得到视频完整本地路径。
python
print(f"开始下载视频: {url} -> {out_path}")
打印下载信息,源地址与本地保存路径。
python
r = requests.get(url, stream=True, timeout=300)
下载视频,
stream=True流式下载,不会一次性把整个大视频全部加载进内存 ,边下载边写磁盘,内存占用低。timeout=300,下载超时5分钟。
python
r.raise_for_status()
下载请求http错误抛出异常。
python
with open(out_path, "wb") as f:
for chunk in r.iter_content(chunk_size=8192):
f.write(chunk)
with open(..., "wb"):wb二进制写入模式 ,视频、图片二进制文件必须wb,不能用w文本模式,否则会出现ascii编码报错。
iter_content(chunk_size=8192):分块读取http流,每次读取8192字节,循环一块块写入磁盘。适合大文件,低内存消耗。
python
return out_path
返回本地视频完整路径,给调用方。
python
if __name__ == "__main__":
Python入口标记:直接运行这个py脚本时,下面代码块执行;如果这个文件被别的文件import导入,则不会执行下面测试代码。
python
if not API_KEY:
raise Exception("请配置 .env 文件 DASHSCOPE_API_KEY")
判断密钥是否读取成功;为空直接抛出异常,提示配置.env。
python
test_prompt = "海边日落,海浪轻轻拍打沙滩,电影级画面"
测试提示词,描述要生成的视频画面。
python
print("提交生成任务...")
tid = submit_task(test_prompt)
调用submit_task提交任务,拿到task_id。
python
print(f"task_id: {tid}")
打印任务ID,可以复制到dashscope网页控制台查看任务详情。
python
remote_video_url = wait_task(tid)
调用wait_task轮询等待生成完成,拿到云端视频临时url。
python
print(f"云端视频地址: {remote_video_url}")
打印阿里云OSS临时链接,链接有有效期,不能长期保存。
python
local_file = download_mp4(remote_video_url)
调用下载函数,把视频保存到本地 ./out/随机uuid.mp4。
python
print(f"✅完成,本地文件:{local_file}")
打印最终本地文件完整路径。
整体执行流程
- load_dotenv读取.env密钥;
- submit_task:POST提交异步视频任务,返回task_id;
- wait_task:循环GET查询task_id状态,成功返回云端url;失败/超时抛异常;
- download_mp4:流式分块下载视频,保存到
./out目录,返回本地路径。
常见坑
.env文件名字不能写错,必须和py脚本同一目录;- 不要复制文档里全角减号,参数、模型名都必须英文半角符号;
- 需要Dashscope账号开通wan2.7‑t2v权限、账户余额充足;
- OSS云端视频url是临时链接,一段时间会失效,务必下载保存本地。
- 函数全部用异常抛出错误,实际业务外层建议加 try‑except捕获异常做错误处理。