Files
dsProject/dsLightRag/JiMeng/Kit/JmCommon.py

150 lines
5.9 KiB
Python
Raw Normal View History

2025-08-19 15:01:48 +08:00
import hashlib
import hmac
import json
import os
import time
from datetime import datetime, timezone
import requests
class JmCommon:
# 请求域名和相关配置
host = "visual.volcengineapi.com"
path = "/"
service = "cv"
region = "cn-north-1"
schema = "https"
version = "2022-08-31"
2025-08-19 15:06:49 +08:00
# API访问凭证 - 请替换为您自己的凭证
2025-08-19 15:01:48 +08:00
ak = "AKLTZjVlOGU1NzA1YWZkNDExMzkzYzY5YTNlOTRmMTMxODg"
sk = "WkdabU9UTXdNVEJpTmpWbE5HVTJZVGxtTnpWbU5XSTBaRGN5TW1NMk5tRQ=="
# 项目路径
project_root = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..", "..", "..", "..", ".."))
base_path = os.path.join(project_root, "src", "main", "python", "com", "dsideal", "aiSupport", "Util", "JiMeng", "Example")
@staticmethod
2025-08-19 15:26:41 +08:00
def sign(key, msg):
2025-08-19 15:01:48 +08:00
"""使用HMAC-SHA256算法计算消息认证码"""
2025-08-19 15:26:41 +08:00
return hmac.new(key, msg.encode('utf-8'), hashlib.sha256).digest()
2025-08-19 15:01:48 +08:00
@staticmethod
2025-08-19 15:26:41 +08:00
def get_signature_key(key, date_stamp, region_name, service_name):
2025-08-19 15:01:48 +08:00
"""生成V4版本的签名密钥"""
2025-08-19 15:26:41 +08:00
k_date = JmCommon.sign(key.encode('utf-8'), date_stamp)
k_region = JmCommon.sign(k_date, region_name)
k_service = JmCommon.sign(k_region, service_name)
k_signing = JmCommon.sign(k_service, 'request')
return k_signing
@staticmethod
def format_query(parameters):
"""格式化查询参数"""
request_parameters_init = ''
for key in sorted(parameters):
request_parameters_init += key + '=' + str(parameters[key]) + '&'
return request_parameters_init[:-1] if request_parameters_init else ''
2025-08-19 15:01:48 +08:00
@staticmethod
def do_request(method, query_list, body, action):
"""发送HTTP请求到火山引擎API"""
date = datetime.now(timezone.utc)
if body is None:
body = b''
2025-08-19 15:26:41 +08:00
# 格式化日期时间
current_date = date.strftime("%Y%m%dT%H%M%SZ")
date_stamp = date.strftime("%Y%m%d")
2025-08-19 15:01:48 +08:00
# 构建查询参数字符串
real_query_list = query_list.copy() if query_list else {}
real_query_list["Action"] = action
real_query_list["Version"] = JmCommon.version
2025-08-19 15:26:41 +08:00
canonical_querystring = JmCommon.format_query(real_query_list)
# 计算请求体哈希值
if isinstance(body, bytes):
body_str = body.decode('utf-8')
else:
body_str = str(body)
payload_hash = hashlib.sha256(body_str.encode('utf-8')).hexdigest()
# 设置请求头相关信息
content_type = "application/json"
signed_headers = 'content-type;host;x-content-sha256;x-date'
canonical_headers = f'content-type:{content_type}\nhost:{JmCommon.host}\nx-content-sha256:{payload_hash}\nx-date:{current_date}\n'
# 构建规范请求字符串
canonical_request = f'{method}\n{JmCommon.path}\n{canonical_querystring}\n{canonical_headers}\n{signed_headers}\n{payload_hash}'
2025-08-19 15:01:48 +08:00
2025-08-19 15:26:41 +08:00
# 构建签名字符串
algorithm = 'HMAC-SHA256'
credential_scope = f'{date_stamp}/{JmCommon.region}/{JmCommon.service}/request'
string_to_sign = f'{algorithm}\n{current_date}\n{credential_scope}\n{hashlib.sha256(canonical_request.encode("utf-8")).hexdigest()}'
2025-08-19 15:01:48 +08:00
# 生成签名密钥并计算签名
2025-08-19 15:26:41 +08:00
signing_key = JmCommon.get_signature_key(JmCommon.sk, date_stamp, JmCommon.region, JmCommon.service)
signature = hmac.new(signing_key, string_to_sign.encode('utf-8'), hashlib.sha256).hexdigest()
2025-08-19 15:01:48 +08:00
# 构建URL
2025-08-19 15:26:41 +08:00
url = f'{JmCommon.schema}://{JmCommon.host}{JmCommon.path}?{canonical_querystring}'
2025-08-19 15:01:48 +08:00
# 设置请求头
headers = {
2025-08-19 15:26:41 +08:00
"X-Date": current_date,
"Authorization": f'{algorithm} Credential={JmCommon.ak}/{credential_scope}, SignedHeaders={signed_headers}, Signature={signature}',
"X-Content-Sha256": payload_hash,
"Content-Type": content_type
2025-08-19 15:01:48 +08:00
}
# 发送请求
try:
2025-08-19 15:06:49 +08:00
print(f"请求URL: {url}")
print(f"请求头: {headers}")
2025-08-19 15:01:48 +08:00
response = requests.request(
method=method,
url=url,
headers=headers,
data=body,
timeout=(30, 30) # 连接超时和读取超时
)
2025-08-19 15:06:49 +08:00
print(f"响应状态码: {response.status_code}")
print(f"响应内容: {response.text}")
2025-08-19 15:01:48 +08:00
response.raise_for_status() # 如果状态码不是200抛出异常
return response.text
except requests.exceptions.RequestException as e:
raise Exception(f"API请求失败: {str(e)}")
@staticmethod
def download_file(file_url, save_file_path):
"""从URL下载文件到指定路径"""
try:
# 确保目录存在
os.makedirs(os.path.dirname(save_file_path), exist_ok=True)
# 下载文件
response = requests.get(file_url, timeout=30)
response.raise_for_status()
with open(save_file_path, 'wb') as f:
f.write(response.content)
file_size = os.path.getsize(save_file_path)
print(f"文件下载成功,保存路径: {save_file_path}, 文件大小: {file_size}字节")
except Exception as e:
print(f"文件下载失败: {str(e)}")
raise Exception(f"文件下载失败: {str(e)}")
@staticmethod
def query_task_result(task_id):
"""查询异步任务结果"""
req_key = "jimeng_vgfm_t2v_l20"
action = "CVSync2AsyncGetResult"
# 创建请求体
req = {
"task_id": task_id,
"req_key": req_key
}
response_body = JmCommon.do_request("POST", {}, json.dumps(req).encode('utf-8'), action)
return json.loads(response_body)