day16-Trae开发换脸微信小程序03
今日内容
0 Python调用Coze换脸工作流
# 1 在coze平台创建一个 工作流【开始--介绍】---》不仅仅在浏览器中用
-为什么要把coze工作流包装成功软件
-我们制作的软件【编写的软件】--》可以扩展--》加入自己的功能
# 2 使用代码调用它【工作流】
-可以用各种语言:python。。。。go,java


# 1 导入包,后续代码中会使用
import requests # pip install requests
import json
import time
import os
from typing import Optional, Dict, Any
'''
个人访问令牌:https://www.coze.cn/open/oauth/pats
'''
# 2 写另一个类:CozeAPI,类中有很多方法
class CozeAPI:
"""Coze API客户端,用于调用Coze的换脸工作流"""
# 2.1 __init__ 类实例化时,会调用 coze_api = CozeAPI()--->完成初始化
def __init__(self, api_key: str = None, workflow_id: str = None):
self.api_key = api_key or 'pat_1gKm8Lk3UKGEH9qLUqdHPg1b6eQalw0jmYzeQVJ1BbpoSJCoXJMhI9YXAfGZDrV4' # 你们的token
self.workflow_id = workflow_id or '7631948968259469339' # 用我的id号
self.base_url = 'https://api.coze.cn'
self.upload_url = f"{self.base_url}/v1/files/upload"
self.run_url = f"{self.base_url}/v1/workflow/run"
self.headers = {'Authorization': f'Bearer {self.api_key}', 'Content-Type': 'application/json'}
# 2.2 获取本地保存路径:换脸成功后,会把换脸的图片,保存到本地
# 当前目录下的:face_swap文件夹下的coze_results 文件夹下 result_任务id号_当前时间.jpg
def _get_save_path(self, task_id: str) -> str:
"""内部方法:生成图片保存路径(精简路径处理逻辑)"""
result_dir = os.path.join('face_swap', 'coze_results')
os.makedirs(result_dir, exist_ok=True)
filename = f"result_{task_id}_{int(time.time())}.jpg"
return os.path.join(result_dir, filename)
# 2.3 把换脸图片图片下载到本地
def download_image(self, image_url: str, task_id: str) -> Optional[str]:
"""下载图片到本地,返回跨平台路径"""
try:
save_path = self._get_save_path(task_id)
resp = requests.get(image_url, stream=True)
resp.raise_for_status()
with open(save_path, 'wb') as f:
for chunk in resp.iter_content(chunk_size=8192):
f.write(chunk)
print(f"图片下载成功: {save_path}")
return save_path.replace('\\', '/')
except Exception as e:
print(f"图片下载失败: {str(e)}")
return None
# 2.4 上传文件:上传Coze服务器 待换脸的两张图片--》功能是一次上传一张,只是我们调用了两次
def upload_file(self, file_path: str) -> str:
"""上传文件到Coze并获取文件ID"""
if not os.path.exists(file_path):
raise FileNotFoundError(f"文件不存在: {file_path}")
try:
print(f"开始上传文件: {file_path}")
with open(file_path, 'rb') as f:
files = {'file': (os.path.basename(file_path), f)}
resp = requests.post(self.upload_url, headers={'Authorization': f'Bearer {self.api_key}'}, files=files)
print(f"上传响应: {resp.status_code} | {resp.text}")
result = resp.json()
if resp.status_code == 200 and result.get('code') == 0 and 'data' in result:
file_id = result['data'].get('id')
if not file_id:
raise Exception(f"未提取到文件ID: {result}")
print(f"文件上传成功,ID: {file_id}")
return file_id
raise Exception(f"文件上传失败: {result}")
except Exception as e:
print(f"文件上传异常: {str(e)}")
raise
# 2.5 执行工作流
def run_workflow(self, source_image: str, target_image: str) -> Dict[str, Any]:
"""运行Coze换脸工作流,返回任务信息"""
try:
# 3.5.1 调用两次,把两张图片传上去--》拿到图片的id
source_id, target_id = self.upload_file(source_image), self.upload_file(target_image)
# 3.5.2 组装成 调用工作流的数据格式
payload = {
"workflow_id": self.workflow_id, # 工作流ID号
"parameters": {
"face": json.dumps({"file_id": source_id}), # face
"backed": json.dumps({"file_id": target_id}), # backed入参
"text": "执行换脸操作" # 可以带可以不带
},
"app_id": "", # 放空
"is_async": True # 是否异步
}
print(f"调用工作流 {self.workflow_id}...")
resp = requests.post(self.run_url, headers=self.headers, json=payload)
if resp.status_code != 200:
raise Exception(f"工作流调用失败: {resp.status_code} | {resp.text}")
result = resp.json()
if (result.get('code') == 0 or result.get('msg') == '') and (task_id := result.get('execute_id')):
print(f"工作流调用成功,任务ID: {task_id}")
# 调用coze工作流成功--》返回 一堆数据,这对数据中有 :task_id:任务id,后续根据这个id查询是否执行完了 workflow_id
return {'code': 0, 'msg': 'success',
'data': {'task_id': task_id, 'workflow_id': self.workflow_id, 'status': 'pending'}}
raise Exception(f"工作流调用失败: {result.get('msg')} | {result}")
except Exception as e:
print(f"工作流调用异常: {str(e)}")
raise
# 2.6 获取工作结果---》任务id号
def get_workflow_result(self, task_id: str) -> Dict[str, Any]:
"""查询工作流执行结果"""
try:
print(f"查询任务 {task_id} 结果...")
# 简化URL拼接(移除模板字符串,直接格式化)
query_url = f"{self.base_url}/v1/workflows/{self.workflow_id}/run_histories/{task_id}"
resp = requests.get(query_url, headers=self.headers)
if resp.status_code != 200:
raise Exception(f"查询失败: {resp.status_code} | {resp.text}")
result = resp.json()
if result.get('code') != 0:
raise Exception(f"查询结果失败: {result.get('msg')} | {result}")
# 提取核心数据
data = result.get('data', [{}])[0]
exec_status = data.get('execute_status', '')
if exec_status == 'Success':
# #####正常拿到结果---》查到任务执行完了---》解析返回结果
return self._parse_success_result(data, task_id)
elif exec_status == 'Fail':
# 查询任务失败--》返回
return {'status': 'failed', 'error_message': '任务执行失败', 'task_id': task_id}
return {'status': 'processing', 'task_id': task_id}
except Exception as e:
print(f"查询结果异常: {str(e)}")
raise
# 2.7 解析查询任务的结果
def _parse_success_result(self, data: Dict[str, Any], task_id: str) -> Dict[str, Any]:
"""内部方法:解析成功的任务结果(拆分复杂的解析逻辑)"""
try:
output = json.loads(data.get('output', '{}'))
result_data = json.loads(output.get('Output', '{}'))
image_url = result_data.get('output')
if not image_url:
return {'status': 'success', 'message': '任务成功但未返回图片', 'task_id': task_id}
# 2.7.1 任务正常执行成功,图片也有了---》下载图片--》保存到本地
local_path = self.download_image(image_url, task_id)
return {
'status': 'success',
'result_image_url': image_url,
'local_image_path': local_path,
'processing_time': data.get('processing_time', 0),
'task_id': task_id
}
except (json.JSONDecodeError, KeyError) as e:
print(f"解析输出失败: {str(e)}")
return {'status': 'success', 'message': '任务成功但解析输出失败', 'task_id': task_id}
# 3 程序的主入口:右键运行,从里面开始执行
if __name__ == '__main__':
try:
# 3.1 类实例化的到对象
coze_api = CozeAPI()
# 3.2 定义两个变量:存放两张图片
source_path, target_path = './test_source.jpg', './test_target.jpg'
print("开始测试Coze换脸工作流...")
# 3.3 运行工作流并获取任务ID:运行工作流--》异步操作
# 工作流提交上去---》拿到一个ID号---》Coze后台就在换脸---》我们的程序可以干其他事
run_result = coze_api.run_workflow(source_path, target_path)
print(f"工作流提交结果: {run_result}")
if run_result.get('code') == 0:
# 3.4 拿到任务id
task_id = run_result['data']['task_id']
print(f"任务ID: {task_id}")
# 3.5 睡了20s
time.sleep(20) # 等待任务处理
# 3.6 查询结果
result = coze_api.get_workflow_result(task_id)
print(f"任务结果: {result}")
# 3.7 有结果,精简结果判断逻辑,把换脸的结果保存到本地
status_map = {
'success': f"✅ 测试成功!\nURL: {result.get('result_image_url')}\n本地路径: {result.get('local_image_path')}",
'processing': "⏳ 任务仍在处理中",
'failed': f"❌ 任务失败: {result.get('error_message')}"
}
print(status_map.get(result.get('status'), "❌ 未知状态"))
except Exception as e:
print(f"❌ 测试失败: {str(e)}")
0.1 如果让AI写,提示词如何写
# 1 纯让AI写 Python调用Coze换脸工作流 写完是有问题的
# 2 我们可以让它写完,我们调---》但是需要大家会python,会网络才行
# 3 因为我们不会代码,所有代码,我们都要让Trae写
-1 写完会有错误
-会代码的人,可以自己改--》代码能力越强,改的越快,越好
-不会代码的人,继续让Trae改---》可能需要花费几天时间,才改好
-这个过程中,你不断学习
# 4 提示词【写完后,可能能有,可能不能用,如果不能用,会报错,把错误给他,让他继续改】:
我编写好了一个Coze的一键换脸工作流,上传两张图片:face和backed,调用工作流就可以完成换脸,调用的API接口参照:https://www.coze.cn/open/playground/workflow_stream_run?workflow_id=7631948968259469339,帮我使用Python完成对该工作流的调用
1 工作流ID是:7631948968259469339
2 API_key是:【你们的】
1 后端环境搭建
后端使用Python+Django+mysql架构--》要在本地运行---》搭建本地的运行环境
- python的解释器环境
- python解释器中要装Django模块:Trae可以帮我们做
- 本地安装mysql:存数据
1.1 Python环境【没讲具体】
# 1 只要学过python的,都知道,我们开发python或者运行python代码,必须要有这个环境
# 2 去python官网,下载python解释器,安装上:使用的版本: python3.11
# 3 安装完成后:打开cmd,输入python

1.3 Trae安装python插件
# 1 本地安装好了python解释器环境,就可以运行python代码了
# 2 我们之前使用Pycharm软件,运行python代码
# 3 现在我们通过配置,让Trae也能运行Python代码:前几次课讲过
1.2 Mysql8.4 安装
# 1 我们的一键换脸小程序:需要存用户的用户名密码,换脸历史登数据---》这些数据都是要存到mysql数据库中的
# 2 mysql数据库 有很多版本:目前企业中,使用 8.x 是最多的,所以我们也使用8.x 版本
# 3 本地开发:代码在本地,所以数据库目前也放在本地【win机器】
-后期上线Linux:代码放到服务器上,数据库也安装在服务器上
# 4 Mysql 数据库管理软件--》有个库【你家】---》有很多表【一个个房间】---》表中有很多数据【房间中放了很多货物】
-库:change_face # 需要我们创建
-表:用户表,换脸历史表。。 # 不需要我们创建,Trae帮我们做
-数据:用户表中:张三,李四,王五的数据 # 在使用软件过程中,产生的,不需要我们插入
# 5 具体例子
# 用户表:User
id name password age
1 zhangsan 123456 18
2 lisi 555555 18
3 wanwu 666666 18
# 换脸历史表 History
id 换脸时间 换脸用户 图片地址
1 2026年4月26号 1 ./a.jpg
2 2026年4月26号 1 ./b.jpg
3 2026年4月26号 2 ./c.jpg
# 6 使用程序操作数据库:安全,可靠,效率高
1.2.1 win 安装
# 1 我很早之前写一了一篇文章:安装mysql :https://zhuanlan.zhihu.com/p/571585588
################## 具体步骤################
# 1 下载mysql8.4.4
-https://downloads.mysql.com/archives/community/
# 2 解压到某个路径下--》不要带中文
-D:\software\mysql-8.4.4-winx64\mysql-8.4.4-winx64
# 3 在 bin所在目录创建 my.ini # 后缀名注意,不要带 .txt
# 4 创建 data文件夹:D:\software\mysql-8.4.4-winx64\mysql-8.4.4-winx64\data\
########## 在 my.ini 中写入
[mysqld]
# 设置3309端口--->如果装过老版本,占了3306,你就会装不上
port=3309
# 设置mysql的安装目录 ---这里输入你安装的文件路径----
basedir=D:\software\mysql-8.4.4-winx64\mysql-8.4.4-winx64\
# 设置mysql数据库的数据的存放目录
datadir=D:\\software\\mysql-8.4.4-winx64\\mysql-8.4.4-winx64\\data\
# 允许最大连接数
max_connections=200
# 允许连接失败的次数。
max_connect_errors=10
# 服务端使用的字符集默认为utf8
character-set-server=utf8mb4
# 创建新表时将使用的默认存储引擎
default-storage-engine=INNODB
[mysql]
# 设置mysql客户端默认字符集
default-character-set=utf8mb4
[client]
# 设置mysql客户端连接服务端时默认使用的端口
port=3309
default-character-set=utf8mb4
# 5 来到mysql解压后的bin路径下(以管理员身份运行)
以管理员打开cmd
D: # 回车
cd D:\software\mysql-8.4.4-winx64\mysql-8.4.4-winx64\bin
# 6 安装mysql 安装完成后Mysql会有一个随机密码(记住这个密码)--》这里可能会出错 dll文件缺失
mysqld --initialize --console
# 密码:9efF/cgks8rh
# 7 把mysql创建成系统服务
mysqld --install mysql844
# 8 启动mysql服务
net start mysql844
# 9 做成服务后,没有开启自启动--》win关机了,再开启,mysql没启动
命令行中执行:net start mysql844
在服务上点右键启动
如果做成了 自动 --》以后重启后,都是自动开启
# 10 做成开机自启动
如下图



1.2.2 修改密码
# 1 打开cmd
# 2 来到这个路径下输入:D:\software\mysql-8.4.4-winx64\mysql-8.4.4-winx64\bin 输入
mysql -uroot -p -P 3309 # 回车后,输入密码,进入后
# 3 改密码
ALTER USER 'root'@'localhost' IDENTIFIED BY 'lqz123?';
FLUSH PRIVILEGES;
quit
# 4 后续命令不讲了--》因为要学很久
# 5 如果密码忘了:粗暴方式
-删data文件夹
-mysqld --initialize --console

1.2.3 navicat可视化操作【收费-破解用】
# 1 在黑色命令下操作数据库,需要会很多命令--》很难记---》使用图形化界面连接操作--》点点的即可
# 2 mysql官方没有提供可视化,只能用命令,有很多第三方,用谁都行
### DBeaver
优点:DBeaver功能比较强大,使用也较便利。缺点:对于系统资源要求较高,运行速度相对较慢,特别是导入大文件时比较明显。官方主页:https://dbeaver.io/
#### Navicat--收费的--》破解--》好用
# 个人没事
# 不要在公司内部使用破解--》这个公司能根据你的ip--》定位到你公司--》发律师函--》告你
优点:Navicat使用普及率较高,功能非常完整,包括比较强大的SQL补全、导入导出、结果集编辑、E-R模型、数据对比、结构对比、数据迁移等,但有部分功能仅企业版才具备。缺点:需要注册为Navicat用户才能够使用,而且定期会失效,需要重新下载和登录申请为免费使用。官方主页:https://navicat.com/
####SQLyog
SQLyog更多的是专注于数据库的管理,包括性能、监控、优化等方面,也提供基础SQL编辑功能,所以在早期,其在DBA群体中比较受欢迎,但是在整体的开发者中,使用比率并不高。缺点:在云时代对于监控与实例管理方面的诉求在降低,在SQL开发与云适配上需求更强,但这方面发展缓慢,而且产品以商业收费版为主。官方主页:https://webyog.com/product/sqlyog/




1.2.4 Trae可视化操作【免费】
# 1 点扩展--》安装mysql插件
# 2 链接即可





2 Trae编写后端
2.1 提示词
根据项目需求: 和项目后端架构文档: 和前端设计图: ,生成智能换脸微信小程序后台Django的项目和代码
要求:
1.项目写入到目录change_face_api中。
2.生成相关表模型,写入到每个app的models中。
3.生成所有接口,并能正常调用。
4.链接数据库地址为:
-host:127.0.0.1
-port:3309
-database:change_face
-user:root
-password:lqz123?
5.Django 后台admin使用django-simpleui美化,项目做好本地化和时区设置。
6.换脸功能对接Coze一键换脸工作流,对接方案参照代码:
-API_KEY:pat_1gKm8Lk3UKGEH9qLUqdHPg1b6eQalw0jmYzeQVJ1BbpoSJCoXJMhI9YXAfGZDrV4
-工作流ID:7631948968259469339
2.2 模型思考超长
# 1 因为Trae从0,开始写一个完成的后端项目--》代码量很大--》代码大模型,会出现思考超长
# 2 做到一半:如果超长了,点继续--》让它继续做即可
2.3 浏览器访问:
# http://localhost:8000/admin/
# 后端有没有bug? 肯定有,我们先不着急改

3 小程序概述
视频:
https://www.bilibili.com/video/BV1WgQdYNERe/
笔记:
https://pan.baidu.com/s/1VTd6S3rJKQ42MRFPsFwaZQ 提取码: bpxa
使用微信用户,一键登录小程序
- 发送短信微信绑定的手机号---》收费
- 企业用户:营业执照

浙公网安备 33010602011771号