|
1 | 1 | # coding=utf-8 |
2 | 2 | import datetime |
| 3 | +import time |
3 | 4 | from typing import Dict, Optional, Any, Iterator |
4 | 5 |
|
5 | 6 | import requests |
@@ -81,13 +82,24 @@ def upload_file_to_oss(self, policy_data, file_stream, file_name): |
81 | 82 | return f"oss://{key}" |
82 | 83 |
|
83 | 84 | 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)}") |
91 | 103 |
|
92 | 104 | def stream( |
93 | 105 | self, |
@@ -129,32 +141,54 @@ def stream( |
129 | 141 | **self.extra_body, |
130 | 142 | "stream": True, |
131 | 143 | } |
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 |
146 | 144 |
|
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 # 成功执行则退出重试循环 |
149 | 182 |
|
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)) # 指数退避 |
157 | 186 | 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)) |
160 | 192 | continue |
| 193 | + else: |
| 194 | + raise Exception(f"请求失败,已重试{max_retries}次: {str(e)}") |
0 commit comments