This commit is contained in:
2025-08-20 07:38:08 +08:00
parent 4ba9171718
commit a503acdae2
7 changed files with 989 additions and 0 deletions

View File

@@ -0,0 +1,123 @@
import os
import json
import logging
import time
from datetime import datetime, timedelta
import requests
import jwt
# 配置日志
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
log = logging.getLogger(__name__)
class KlCommon:
# 获取项目根目录路径
project_root = os.path.abspath(os.path.join(os.path.dirname(__file__), '../../../../..')).replace('\\', '/') + '/dsAi'
# 拼接相对路径
base_path = project_root + '/src/main/java/com/dsideal/aiSupport/Util/KeLing/Example/'
ak = 'c992fd02624d4900a93ca3b6da03d9e9' # 填写access key
sk = 'b37f67a00eb44f9bb57e4d530c328e1d' # 填写secret key
@staticmethod
def get_jwt():
try:
# 有效时间,此处示例代表当前时间+1800s(30min)
expired_at = datetime.utcnow() + timedelta(seconds=1800)
# 开始生效的时间,此处示例代表当前时间-5秒
not_before = datetime.utcnow() - timedelta(seconds=5)
# 构建JWT令牌
payload = {
'iss': KlCommon.ak,
'exp': expired_at,
'nbf': not_before
}
# 使用HS256算法签名
jwt_token = jwt.encode(payload, KlCommon.sk, algorithm='HS256', headers={'alg': 'HS256'})
return jwt_token
except Exception as e:
log.error(f"获取JWT令牌失败: {str(e)}")
return None
@staticmethod
def download_file(file_url, save_file_path):
"""
从URL下载文件到指定路径
@param file_url: 文件URL
@param save_file_path: 保存路径
@throws Exception: 下载过程中的异常
"""
try:
# 发送GET请求下载文件
response = requests.get(file_url, stream=True)
response.raise_for_status() # 检查响应状态码
# 保存文件
with open(save_file_path, 'wb') as f:
for chunk in response.iter_content(chunk_size=8192):
f.write(chunk)
file_size = os.path.getsize(save_file_path)
log.info(f"文件下载成功,保存路径: {save_file_path}, 文件大小: {file_size}字节")
except Exception as e:
log.error(f"文件下载失败: {str(e)}")
raise Exception(f"文件下载失败: {str(e)}") from e
@staticmethod
def query_task_status(task_id, query_path, log_prefix):
"""
通用查询任务状态方法
@param task_id: 任务ID
@param query_path: 查询路径
@param log_prefix: 日志前缀,用于区分不同类型的查询
@return: 任务结果
@throws Exception: 异常信息
"""
# 获取JWT令牌
jwt_token = KlCommon.get_jwt()
if not jwt_token:
raise Exception("获取JWT令牌失败")
# 构建请求URL
url = f"https://api.klingai.com{query_path}{task_id}"
# 设置请求头
headers = {
'Content-Type': 'application/json',
'Authorization': f'Bearer {jwt_token}'
}
# 发送GET请求
try:
response = requests.get(url, headers=headers)
response.raise_for_status() # 检查响应状态码
# 解析响应
response_body = response.text
response_json = json.loads(response_body)
log.info(f"{log_prefix}查询任务状态响应:{response_body}")
# 检查响应状态
code = response_json.get('code')
if code != 0:
message = response_json.get('message', '')
from .KlErrorCode import KlErrorCode
solution = KlErrorCode.get_solution_by_code(code)
error_msg = f"{log_prefix}查询任务状态失败:[{code}] {message} - {solution}"
raise Exception(error_msg)
return response_json
except requests.exceptions.RequestException as e:
log.error(f"{log_prefix}查询任务状态请求异常: {str(e)}")
raise Exception(f"{log_prefix}查询任务状态请求异常: {str(e)}") from e
except json.JSONDecodeError as e:
log.error(f"{log_prefix}解析响应JSON失败: {str(e)}")
raise Exception(f"{log_prefix}解析响应JSON失败: {str(e)}") from e
except Exception as e:
log.error(f"{log_prefix}查询任务状态发生未知异常: {str(e)}")
raise

View File

@@ -0,0 +1,90 @@
from enum import Enum
class KlErrorCode(Enum):
"""可灵AI API错误码枚举"""
SUCCESS = (0, "请求成功", "请求成功")
# 身份验证错误 (401)
AUTH_FAILED = (1000, "身份验证失败", "检查Authorization是否正确")
AUTH_EMPTY = (1001, "Authorization为空", "在RequestHeader中填写正确的Authorization")
AUTH_INVALID = (1002, "Authorization值非法", "在RequestHeader中填写正确的Authorization")
AUTH_NOT_EFFECTIVE = (1003, "Authorization未到有效时间", "检查token的开始生效时间等待生效或重新签发")
AUTH_EXPIRED = (1004, "Authorization已失效", "检查token的有效期重新签发")
# 账户异常 (429)
ACCOUNT_EXCEPTION = (1100, "账户异常", "检查账户配置信息")
ACCOUNT_ARREARS = (1101, "账户欠费 (后付费场景)", "进行账户充值,确保余额充足")
RESOURCE_EXHAUSTED = (1102, "资源包已用完/已过期(预付费场景)", "购买额外的资源包,或开通后付费服务(如有)")
# 权限错误 (403)
NO_PERMISSION = (1103, "请求的资源无权限,如接口/模型", "检查账户权限")
# 请求参数非法 (400/404)
PARAM_INVALID = (1200, "请求参数非法", "检查请求参数是否正确")
PARAM_ERROR = (1201, "参数非法如key写错或value非法", "参考返回体中message字段的具体信息修改请求参数")
METHOD_INVALID = (1202, "请求的method无效", "查看接口文档使用正确的requestmethod")
RESOURCE_NOT_EXIST = (1203, "请求的资源不存在,如模型", "参考返回体中message字段的具体信息修改请求参数")
# 触发策略 (400/429)
POLICY_TRIGGERED = (1300, "触发平台策略", "检查是否触发平台策略")
CONTENT_SECURITY = (1301, "触发平台的内容安全策略", "检查输入内容,修改后重新发起请求")
RATE_LIMIT = (1302, "API请求过快超过平台速率限制", "降低请求频率、稍后重试,或联系客服增加限额")
CONCURRENT_LIMIT = (1303, "并发或QPS超出预付费资源包限制", "降低请求频率、稍后重试,或联系客服增加限额")
IP_WHITELIST = (1304, "触发平台的IP白名单策略", "联系客服")
# 内部错误 (500/503/504)
INTERNAL_ERROR = (5000, "服务器内部错误", "稍后重试,或联系客服")
SERVICE_UNAVAILABLE = (5001, "服务器暂时不可用,通常是在维护", "稍后重试,或联系客服")
INTERNAL_TIMEOUT = (5002, "服务器内部超时,通常是发生积压", "稍后重试,或联系客服")
def __init__(self, code, message, solution):
self.code = code
self.message = message
self.solution = solution
@staticmethod
def get_by_code(code):
"""根据错误码获取枚举实例"""
for error_code in KlErrorCode:
if error_code.code == code:
return error_code
return None
@staticmethod
def get_message_by_code(code):
"""获取错误消息"""
error_code = KlErrorCode.get_by_code(code)
return error_code.message if error_code else "未知错误"
@staticmethod
def get_solution_by_code(code):
"""获取解决方案"""
error_code = KlErrorCode.get_by_code(code)
return error_code.solution if error_code else "请联系客服"
@staticmethod
def is_success(code):
"""检查是否成功"""
return code == KlErrorCode.SUCCESS.code
@staticmethod
def is_retryable(code):
"""检查是否需要重试"""
return code in [
KlErrorCode.RATE_LIMIT.code,
KlErrorCode.CONCURRENT_LIMIT.code,
KlErrorCode.INTERNAL_ERROR.code,
KlErrorCode.SERVICE_UNAVAILABLE.code,
KlErrorCode.INTERNAL_TIMEOUT.code
]
@staticmethod
def is_account_issue(code):
"""检查是否是账户问题"""
return code in [
KlErrorCode.ACCOUNT_EXCEPTION.code,
KlErrorCode.ACCOUNT_ARREARS.code,
KlErrorCode.RESOURCE_EXHAUSTED.code,
KlErrorCode.NO_PERMISSION.code
]