@@ -65,21 +65,50 @@ def _request(self, method: str, endpoint: str, **kwargs) -> requests.Response:
6565 url = urljoin (self .base_url , endpoint )
6666 headers = kwargs .pop ("headers" , {})
6767 headers .update (self ._get_headers ())
68-
69- response = requests .request (method , url , headers = headers , ** kwargs )
7068
71- if not response .ok :
72- error_msg = f"API request failed: { response .status_code } "
73- error_data = {}
74- try :
75- error_data = response .json ()
76- error_msg = f"{ error_msg } - { error_data .get ('error' , {}).get ('message' , '' )} "
77- except RequestsJSONDecodeError :
78- pass
79-
80- raise DifyAPIError (error_msg , status_code = response .status_code , error_data = error_data )
69+ # 设置重试机制
70+ max_retries = kwargs .pop ("max_retries" , 2 )
71+ retry_delay = kwargs .pop ("retry_delay" , 1 )
72+ timeout = kwargs .pop ("timeout" , 30 )
8173
82- return response
74+ # 添加超时参数
75+ kwargs ["timeout" ] = timeout
76+
77+ for attempt in range (max_retries + 1 ):
78+ try :
79+ response = requests .request (method , url , headers = headers , ** kwargs )
80+
81+ if not response .ok :
82+ error_msg = f"API request failed: { response .status_code } "
83+ error_data = {}
84+ try :
85+ error_data = response .json ()
86+ error_msg = f"{ error_msg } - { error_data .get ('error' , {}).get ('message' , '' )} "
87+ except RequestsJSONDecodeError :
88+ if response .text :
89+ error_msg = f"{ error_msg } - { response .text [:100 ]} "
90+
91+ # 如果是可重试的错误码,并且还有重试次数,则重试
92+ if response .status_code in [429 , 500 , 502 , 503 , 504 ] and attempt < max_retries :
93+ print (f"请求失败,状态码: { response .status_code } ,{ attempt + 1 } 秒后重试..." )
94+ import time
95+ time .sleep (retry_delay )
96+ continue
97+
98+ # 否则抛出异常
99+ raise DifyAPIError (error_msg , status_code = response .status_code , error_data = error_data )
100+
101+ return response
102+
103+ except (requests .RequestException , ConnectionError ) as e :
104+ # 如果是网络错误且还有重试次数,则重试
105+ if attempt < max_retries :
106+ print (f"网络错误: { str (e )} ,{ attempt + 1 } 秒后重试..." )
107+ import time
108+ time .sleep (retry_delay )
109+ continue
110+
111+ raise DifyAPIError (f"网络请求异常: { str (e )} " )
83112
84113 def get (self , endpoint : str , ** kwargs ) -> Dict [str , Any ]:
85114 """
@@ -102,10 +131,10 @@ def get(self, endpoint: str, **kwargs) -> Dict[str, Any]:
102131 return {}
103132 return response .json ()
104133 except RequestsJSONDecodeError as e :
105- # 捕获JSON解析错误,提供更有用的错误消息
106- error_msg = f"无法解析API响应为JSON: { str ( e ) } "
107- error_data = { "response_text" : response .text [:100 ], "endpoint" : endpoint }
108- raise DifyAPIError ( error_msg , response . status_code , error_data ) from e
134+ # 捕获JSON解析错误,打印警告信息并返回空字典
135+ print ( f"警告: 无法解析API响应为JSON ( { endpoint } )" )
136+ print ( f"响应内容: { response .text [:100 ]} " )
137+ return {}
109138
110139 def post (self , endpoint : str , data : Dict [str , Any ] = None , json_data : Dict [str , Any ] = None , ** kwargs ) -> Dict [str , Any ]:
111140 """
@@ -130,10 +159,10 @@ def post(self, endpoint: str, data: Dict[str, Any] = None, json_data: Dict[str,
130159 return {}
131160 return response .json ()
132161 except RequestsJSONDecodeError as e :
133- # 捕获JSON解析错误,提供更有用的错误消息
134- error_msg = f"无法解析API响应为JSON: { str ( e ) } "
135- error_data = { "response_text" : response .text [:100 ], "endpoint" : endpoint }
136- raise DifyAPIError ( error_msg , response . status_code , error_data ) from e
162+ # 捕获JSON解析错误,打印警告信息并返回空字典
163+ print ( f"警告: 无法解析API响应为JSON ( { endpoint } )" )
164+ print ( f"响应内容: { response .text [:100 ]} " )
165+ return {}
137166
138167 def post_stream (self , endpoint : str , json_data : Dict [str , Any ], ** kwargs ) -> Generator [Dict [str , Any ], None , None ]:
139168 """
@@ -153,30 +182,66 @@ def post_stream(self, endpoint: str, json_data: Dict[str, Any], **kwargs) -> Gen
153182 url = urljoin (self .base_url , endpoint )
154183 headers = kwargs .pop ("headers" , {})
155184 headers .update (self ._get_headers ())
156-
157- with requests .post (url , json = json_data , headers = headers , stream = True , ** kwargs ) as response :
158- if not response .ok :
159- error_msg = f"API request failed: { response .status_code } "
160- error_data = {}
161- try :
162- error_data = response .json ()
163- error_msg = f"{ error_msg } - { error_data .get ('error' , {}).get ('message' , '' )} "
164- except RequestsJSONDecodeError :
165- pass
166-
167- raise DifyAPIError (error_msg , status_code = response .status_code , error_data = error_data )
168-
169- # 处理SSE流式响应
170- for line in response .iter_lines ():
171- if line :
172- line = line .decode ('utf-8' )
173- if line .startswith ('data: ' ):
174- data = line [6 :] # 移除 'data: ' 前缀
185+
186+ # 设置重试机制
187+ max_retries = kwargs .pop ("max_retries" , 2 )
188+ retry_delay = kwargs .pop ("retry_delay" , 1 )
189+ timeout = kwargs .pop ("timeout" , 60 ) # 流式请求需要更长的超时时间
190+
191+ # 添加超时参数
192+ kwargs ["timeout" ] = timeout
193+
194+ for attempt in range (max_retries + 1 ):
195+ try :
196+ with requests .post (url , json = json_data , headers = headers , stream = True , ** kwargs ) as response :
197+ if not response .ok :
198+ error_msg = f"API request failed: { response .status_code } "
199+ error_data = {}
175200 try :
176- yield json .loads (data )
177- except json .JSONDecodeError :
178- # 忽略无法解析的行
179- pass
201+ error_data = response .json ()
202+ error_msg = f"{ error_msg } - { error_data .get ('error' , {}).get ('message' , '' )} "
203+ except RequestsJSONDecodeError :
204+ # 如果无法解析为JSON,提供一个简单的错误消息
205+ error_msg = f"{ error_msg } - 响应无法解析为JSON"
206+ if response .text :
207+ print (f"响应内容: { response .text [:100 ]} " )
208+
209+ # 如果是可重试的错误码,并且还有重试次数,则重试
210+ if response .status_code in [429 , 500 , 502 , 503 , 504 ] and attempt < max_retries :
211+ print (f"请求失败,状态码: { response .status_code } ,{ attempt + 1 } 秒后重试..." )
212+ import time
213+ time .sleep (retry_delay )
214+ continue
215+
216+ raise DifyAPIError (error_msg , status_code = response .status_code , error_data = error_data )
217+
218+ # 处理SSE流式响应
219+ for line in response .iter_lines ():
220+ if line :
221+ line = line .decode ('utf-8' )
222+ if line .startswith ('data: ' ):
223+ data = line [6 :] # 移除 'data: ' 前缀
224+ try :
225+ yield json .loads (data )
226+ except json .JSONDecodeError as e :
227+ # 打印警告信息并继续处理
228+ print (f"警告: 无法解析流式响应行为JSON: { data [:100 ]} " )
229+ # 返回一个带有错误信息的字典,而不是抛出异常
230+ yield {"error" : "JSON解析错误" , "raw_data" : data [:100 ]}
231+
232+ # 如果成功完成了迭代,就跳出重试循环
233+ break
234+
235+ except (requests .RequestException , ConnectionError ) as e :
236+ # 如果是网络错误且还有重试次数,则重试
237+ if attempt < max_retries :
238+ print (f"网络错误: { str (e )} ,{ attempt + 1 } 秒后重试..." )
239+ import time
240+ time .sleep (retry_delay )
241+ continue
242+
243+ # 如果已经重试了所有次数仍失败,抛出异常
244+ raise DifyAPIError (f"流式请求异常: { str (e )} " )
180245
181246 # 通用方法 - 这些方法在多个子类中重复出现,可以移到基类
182247
0 commit comments