Skip to content

Commit ab434b0

Browse files
committed
fix: add retry mechanism for file uploads and response handling in image.py
1 parent 775aa91 commit ab434b0

File tree

3 files changed

+71
-36
lines changed

3 files changed

+71
-36
lines changed

apps/application/flow/step_node/video_understand_step_node/impl/base_video_understand_node.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -124,28 +124,28 @@ def generate_history_ai_message(self, chat_record):
124124
if self.node.id == val['node_id'] and 'video_list' in val:
125125
if val['dialogue_type'] == 'WORKFLOW':
126126
return chat_record.get_ai_message()
127-
return AIMessage(content=val['answer'])
127+
return AIMessage(content=val['answer'] or '')
128128
return chat_record.get_ai_message()
129129

130130
def generate_history_human_message_for_details(self, chat_record):
131131
for data in chat_record.details.values():
132132
if self.node.id == data['node_id'] and 'video_list' in data:
133133
video_list = data['video_list']
134-
if len(video_list) == 0 or data['dialogue_type'] == 'WORKFLOW':
134+
# 增加对 None 和空列表的检查
135+
if not video_list or len(video_list) == 0 or data['dialogue_type'] == 'WORKFLOW':
135136
return HumanMessage(content=chat_record.problem_text)
136137
file_id_list = [video.get('file_id') for video in video_list]
137138
return HumanMessage(content=[
138139
{'type': 'text', 'text': data['question']},
139140
*[{'type': 'video_url', 'video_url': {'url': f'./oss/file/{file_id}'}} for file_id in file_id_list]
140-
141141
])
142142
return HumanMessage(content=chat_record.problem_text)
143143

144144
def get_history_message(self, history_chat_record, dialogue_number, video_model):
145145
start_index = len(history_chat_record) - dialogue_number
146146
history_message = reduce(lambda x, y: [*x, *y], [
147147
[self.generate_history_human_message(history_chat_record[index], video_model),
148-
self.generate_history_ai_message(history_chat_record[index]), video_model]
148+
self.generate_history_ai_message(history_chat_record[index])]
149149
for index in
150150
range(start_index if start_index > 0 else 0, len(history_chat_record))], [])
151151
return history_message

apps/models_provider/impl/aliyun_bai_lian_model_provider/model/image.py

Lines changed: 66 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# coding=utf-8
22
import datetime
3+
import time
34
from typing import Dict, Optional, Any, Iterator
45

56
import requests
@@ -81,13 +82,24 @@ def upload_file_to_oss(self, policy_data, file_stream, file_name):
8182
return f"oss://{key}"
8283

8384
def upload_file_and_get_url(self, file_stream, file_name):
84-
"""上传文件并获取URL"""
85-
# 1. 获取上传凭证,上传凭证接口有限流,超出限流将导致请求失败
86-
policy_data = self.get_upload_policy(self.openai_api_key.get_secret_value(), self.model_name)
87-
# 2. 上传文件到OSS
88-
oss_url = self.upload_file_to_oss(policy_data, file_stream, file_name)
89-
90-
return oss_url
85+
max_retries = 3
86+
87+
retry_delay = 1 # 初始重试延迟(秒)
88+
89+
for attempt in range(max_retries):
90+
try:
91+
# 1. 获取上传凭证,上传凭证接口有限流,超出限流将导致请求失败
92+
policy_data = self.get_upload_policy(self.openai_api_key.get_secret_value(), self.model_name)
93+
# 2. 上传文件到OSS
94+
oss_url = self.upload_file_to_oss(policy_data, file_stream, file_name)
95+
return oss_url
96+
except Exception as e:
97+
if attempt < max_retries - 1:
98+
# 指数退避策略
99+
time.sleep(retry_delay * (2 ** attempt))
100+
continue
101+
else:
102+
raise Exception(f"文件上传失败,已重试{max_retries}次: {str(e)}")
91103

92104
def stream(
93105
self,
@@ -129,32 +141,54 @@ def stream(
129141
**self.extra_body,
130142
"stream": True,
131143
}
132-
response = requests.post(url, headers=headers, json=data, stream=True)
133-
if response.status_code != 200:
134-
raise Exception(f"Failed to get response: {response.text}")
135-
for line in response.iter_lines():
136-
if line:
137-
try:
138-
decoded_line = line.decode('utf-8')
139-
# 检查是否是有效的SSE数据行
140-
if decoded_line.startswith('data: '):
141-
# 提取JSON部分
142-
json_str = decoded_line[6:] # 移除 'data: ' 前缀
143-
# 检查是否是结束标记
144-
if json_str.strip() == '[DONE]':
145-
continue
146144

147-
# 尝试解析JSON
148-
chunk_data = json.loads(json_str)
145+
# 增加重试机制
146+
max_retries = 3
147+
retry_delay = 1
148+
149+
for attempt in range(max_retries):
150+
try:
151+
response = requests.post(url, headers=headers, json=data, stream=True, timeout=30)
152+
if response.status_code != 200:
153+
raise Exception(f"Failed to get response: {response.text}")
154+
155+
for line in response.iter_lines():
156+
if line:
157+
try:
158+
decoded_line = line.decode('utf-8')
159+
# 检查是否是有效的SSE数据行
160+
if decoded_line.startswith('data: '):
161+
# 提取JSON部分
162+
json_str = decoded_line[6:] # 移除 'data: ' 前缀
163+
# 检查是否是结束标记
164+
if json_str.strip() == '[DONE]':
165+
continue
166+
167+
# 尝试解析JSON
168+
chunk_data = json.loads(json_str)
169+
170+
if 'choices' in chunk_data and chunk_data['choices']:
171+
delta = chunk_data['choices'][0].get('delta', {})
172+
content = delta.get('content', '')
173+
if content:
174+
yield AIMessage(content=content)
175+
except json.JSONDecodeError:
176+
# 忽略无法解析的行
177+
continue
178+
except Exception as e:
179+
# 处理其他可能的异常
180+
continue
181+
break # 成功执行则退出重试循环
149182

150-
if 'choices' in chunk_data and chunk_data['choices']:
151-
delta = chunk_data['choices'][0].get('delta', {})
152-
content = delta.get('content', '')
153-
if content:
154-
yield AIMessage(content=content)
155-
except json.JSONDecodeError:
156-
# 忽略无法解析的行
183+
except (requests.exceptions.ProxyError, requests.exceptions.ConnectionError) as e:
184+
if attempt < max_retries - 1:
185+
time.sleep(retry_delay * (2 ** attempt)) # 指数退避
157186
continue
158-
except Exception as e:
159-
# 处理其他可能的异常
187+
else:
188+
raise Exception(f"网络连接失败,已重试{max_retries}次: {str(e)}")
189+
except Exception as e:
190+
if attempt < max_retries - 1:
191+
time.sleep(retry_delay * (2 ** attempt))
160192
continue
193+
else:
194+
raise Exception(f"请求失败,已重试{max_retries}次: {str(e)}")

apps/models_provider/impl/volcanic_engine_model_provider/model/image.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ def upload_file_and_get_url(self, file_stream, file_name):
3232
return f'data:{video_format};base64,{base64_video}'
3333

3434

35+
3536
def get_video_format(file_name):
3637
extension = file_name.split('.')[-1].lower()
3738
format_map = {

0 commit comments

Comments
 (0)