Files
task-executer/generic_api_task.py
2025-12-09 15:16:37 +08:00

120 lines
5.6 KiB
Python
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.
"""呼叫任务API函数"""
from celery_app import app
from datetime import datetime
import logging
import requests
from api_config import API_CONFIG, RETRY_CONFIG
logger = logging.getLogger(__name__)
@app.task(bind=True, max_retries=None)
def generic_api_call(self, api_key='main_api', custom_payload=None):
"""调用呼叫任务API
Args:
api_key: 呼叫任务API配置的键名(如 'call_api', 'voice_api')
custom_payload: 自定义呼叫参数,如果为None则使用默认参数
"""
current_time = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
logger.info(f"呼叫任务API开始执行 - 当前时间: {current_time}")
# 获取重试配置
max_retries = RETRY_CONFIG['max_retries']
retry_delay = RETRY_CONFIG['retry_delay']
retry_on_status = RETRY_CONFIG['retry_on_status']
# 获取呼叫任务API配置
call_config = API_CONFIG[api_key]
call_url = call_config['url']
method = call_config['method'].upper()
headers = call_config['headers']
timeout = call_config['timeout']
# 构建呼叫参数
if custom_payload is None:
# 直接使用配置文件中的body作为呼叫参数
payload = call_config['body']
else:
payload = custom_payload
try:
logger.info(f"正在调用呼叫任务API: {method} {call_url}")
# 根据method选择请求方式
if method == 'POST':
response = requests.post(call_url, headers=headers, json=payload, timeout=timeout)
elif method == 'GET':
response = requests.get(call_url, headers=headers, params=payload, timeout=timeout)
elif method == 'PUT':
response = requests.put(call_url, headers=headers, json=payload, timeout=timeout)
elif method == 'DELETE':
response = requests.delete(call_url, headers=headers, timeout=timeout)
else:
raise ValueError(f"不支持的HTTP方法: {method}")
# 检查响应状态
if response.status_code in [200, 201, 204]: # 成功状态码
try:
result_data = response.json()
except:
result_data = {'response': response.text}
logger.info(f"呼叫任务API调用成功,响应数据: {result_data}")
print(f"[{current_time}] ✅ 呼叫任务API成功 - {method} {call_url}")
return {
'status': 'success',
'message': f'呼叫任务API调用成功 ({method})',
'response': result_data,
'timestamp': current_time,
'retry_count': getattr(self.request, 'retries', 0),
'call_api_key': api_key
}
elif response.status_code in retry_on_status:
# 需要重试的状态码
current_retry = getattr(self.request, 'retries', 0)
if current_retry < max_retries:
logger.warning(f"呼叫任务API需要重试,当前重试次数: {current_retry + 1}/{max_retries}")
print(f"[{current_time}] 🔄 呼叫任务API失败,正在重试 ({current_retry + 1}/{max_retries}) - 状态码: {response.status_code}")
raise self.retry(countdown=retry_delay, exc=Exception(f"呼叫任务API失败,状态码: {response.status_code}"))
else:
logger.error(f"呼叫任务API失败,已达到最大重试次数: {max_retries}")
print(f"[{current_time}] ❌ 呼叫任务API失败,已达到最大重试次数 - 状态码: {response.status_code}")
return {
'status': 'failed',
'message': f'呼叫任务API失败,已达到最大重试次数: {max_retries}',
'response': response.text,
'timestamp': current_time,
'retry_count': current_retry + 1,
'call_api_key': api_key
}
else:
# 其他失败状态码,不重试
logger.error(f"呼叫任务API失败,状态码: {response.status_code}, 响应: {response.text}")
print(f"[{current_time}] ❌ 呼叫任务API失败 - 状态码: {response.status_code}")
return {
'status': 'failed',
'message': f'呼叫任务API失败,状态码: {response.status_code}',
'response': response.text,
'timestamp': current_time,
'retry_count': getattr(self.request, 'retries', 0),
'call_api_key': api_key
}
except requests.exceptions.RequestException as e:
# 网络异常,需要重试
current_retry = getattr(self.request, 'retries', 0)
if current_retry < max_retries:
logger.warning(f"呼叫任务API异常,需要重试,当前重试次数: {current_retry + 1}/{max_retries}")
print(f"[{current_time}] 🔄 呼叫任务API异常,正在重试 ({current_retry + 1}/{max_retries}) - 异常: {str(e)}")
raise self.retry(countdown=retry_delay, exc=e)
else:
logger.error(f"呼叫任务API异常,已达到最大重试次数: {max_retries}")
print(f"[{current_time}] ❌ 呼叫任务API异常,已达到最大重试次数 - 异常: {str(e)}")
return {
'status': 'error',
'message': f'呼叫任务API异常,已达到最大重试次数: {max_retries}',
'error': str(e),
'timestamp': current_time,
'retry_count': current_retry + 1,
'call_api_key': api_key
}