Update app.py
Browse files
app.py
CHANGED
@@ -8,6 +8,7 @@ import psutil
|
|
8 |
import random
|
9 |
import threading
|
10 |
import time
|
|
|
11 |
import weakref
|
12 |
from dataclasses import dataclass, field
|
13 |
from typing import Any, Optional, Tuple, List, Dict
|
@@ -32,6 +33,9 @@ API_TOKEN = os.environ.get("API_TOKEN", "")
|
|
32 |
if not API_TOKEN:
|
33 |
raise ValueError("环境变量中未设置API_TOKEN")
|
34 |
|
|
|
|
|
|
|
35 |
# 外部链接
|
36 |
DISCORD_LINK = os.environ.get("DISCORD_LINK", "https://discord.com/invite/AtRtbe9W8w")
|
37 |
APP_INDEX_LINK = os.environ.get("APP_INDEX_LINK", "https://app.nieta.art/")
|
@@ -129,6 +133,49 @@ def validate_dimensions(width: int, height: int) -> tuple[int, int]:
|
|
129 |
return width, height
|
130 |
|
131 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
132 |
class PolishClient:
|
133 |
"""提示词润色客户端"""
|
134 |
|
@@ -171,10 +218,21 @@ async def polish_prompt(prompt: str) -> str:
|
|
171 |
if polish_client is None:
|
172 |
polish_client = PolishClient()
|
173 |
|
174 |
-
|
175 |
-
|
176 |
-
|
177 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
178 |
|
179 |
|
180 |
# 核心类定义
|
@@ -410,7 +468,14 @@ class ImageClient:
|
|
410 |
return None, result["error"]
|
411 |
|
412 |
except Exception as e:
|
413 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
414 |
return None, f"生成图片时发生错误: {str(e)}"
|
415 |
finally:
|
416 |
gc.collect()
|
@@ -575,7 +640,14 @@ async def infer(
|
|
575 |
except gr.Error:
|
576 |
raise
|
577 |
except Exception as e:
|
578 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
579 |
raise gr.Error(f"生成图像时发生意外错误: {str(e)}")
|
580 |
finally:
|
581 |
gc.collect()
|
@@ -820,14 +892,27 @@ def main():
|
|
820 |
except KeyboardInterrupt:
|
821 |
logger.info("接收到键盘中断,正在关闭...")
|
822 |
except Exception as e:
|
823 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
824 |
raise
|
825 |
finally:
|
826 |
# 确保资源清理
|
827 |
try:
|
828 |
asyncio.run(cleanup_resources())
|
829 |
except Exception as e:
|
830 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
831 |
logger.info("应用已退出")
|
832 |
|
833 |
|
|
|
8 |
import random
|
9 |
import threading
|
10 |
import time
|
11 |
+
import traceback
|
12 |
import weakref
|
13 |
from dataclasses import dataclass, field
|
14 |
from typing import Any, Optional, Tuple, List, Dict
|
|
|
33 |
if not API_TOKEN:
|
34 |
raise ValueError("环境变量中未设置API_TOKEN")
|
35 |
|
36 |
+
# 飞书通知配置
|
37 |
+
CHAT_WEBHOOK_URL = os.environ.get("CHAT_WEBHOOK_URL", "")
|
38 |
+
|
39 |
# 外部链接
|
40 |
DISCORD_LINK = os.environ.get("DISCORD_LINK", "https://discord.com/invite/AtRtbe9W8w")
|
41 |
APP_INDEX_LINK = os.environ.get("APP_INDEX_LINK", "https://app.nieta.art/")
|
|
|
133 |
return width, height
|
134 |
|
135 |
|
136 |
+
def feishu_notify(message: str):
|
137 |
+
"""发送飞书通知(异步非阻塞)"""
|
138 |
+
threading.Thread(target=_send_feishu_notify, args=(message,)).start()
|
139 |
+
|
140 |
+
|
141 |
+
def _send_feishu_notify(message: str):
|
142 |
+
"""发送飞书通知的内部实现"""
|
143 |
+
try:
|
144 |
+
headers = {
|
145 |
+
"Content-Type": "application/json",
|
146 |
+
}
|
147 |
+
content = {
|
148 |
+
"msg_type": "text",
|
149 |
+
"content": {
|
150 |
+
"text": message,
|
151 |
+
},
|
152 |
+
}
|
153 |
+
|
154 |
+
with httpx.Client(timeout=10.0) as client:
|
155 |
+
response = client.post(CHAT_WEBHOOK_URL, headers=headers, json=content)
|
156 |
+
if response.status_code == 200:
|
157 |
+
logger.info("飞书通知发送成功")
|
158 |
+
else:
|
159 |
+
logger.warning(f"飞书通知发送失败: {response.status_code}")
|
160 |
+
except Exception as e:
|
161 |
+
logger.error(f"发送飞书通知时出错: {str(e)}")
|
162 |
+
|
163 |
+
|
164 |
+
def format_error_for_notification(error_type: str, error_message: str, traceback_str: str) -> str:
|
165 |
+
"""格式化错误信息用于飞书通知"""
|
166 |
+
return f"""
|
167 |
+
🚨 应用错误警报
|
168 |
+
|
169 |
+
错误类型: {error_type}
|
170 |
+
错误信息: {error_message}
|
171 |
+
|
172 |
+
详细错误栈:
|
173 |
+
{traceback_str}
|
174 |
+
|
175 |
+
时间: {time.strftime('%Y-%m-%d %H:%M:%S')}
|
176 |
+
"""
|
177 |
+
|
178 |
+
|
179 |
class PolishClient:
|
180 |
"""提示词润色客户端"""
|
181 |
|
|
|
218 |
if polish_client is None:
|
219 |
polish_client = PolishClient()
|
220 |
|
221 |
+
try:
|
222 |
+
logger.info(f"润色提示词: {prompt[:50]}...")
|
223 |
+
polished_prompt = await polish_client.polish_text(prompt)
|
224 |
+
logger.info("提示词润色完成")
|
225 |
+
return polished_prompt
|
226 |
+
except Exception as e:
|
227 |
+
error_message = f"提示词润色异常: {str(e)}"
|
228 |
+
traceback_str = traceback.format_exc()
|
229 |
+
logger.error(error_message)
|
230 |
+
|
231 |
+
# 发送飞书通知
|
232 |
+
notification_message = format_error_for_notification("PolishPromptError", error_message, traceback_str)
|
233 |
+
feishu_notify(notification_message)
|
234 |
+
|
235 |
+
return prompt # 返回原始提示词作为fallback
|
236 |
|
237 |
|
238 |
# 核心类定义
|
|
|
468 |
return None, result["error"]
|
469 |
|
470 |
except Exception as e:
|
471 |
+
error_message = f"生成图片异常: {str(e)}"
|
472 |
+
traceback_str = traceback.format_exc()
|
473 |
+
logger.error(error_message)
|
474 |
+
|
475 |
+
# 发送飞书通知
|
476 |
+
notification_message = format_error_for_notification("ImageGenerationError", error_message, traceback_str)
|
477 |
+
feishu_notify(notification_message)
|
478 |
+
|
479 |
return None, f"生成图片时发生错误: {str(e)}"
|
480 |
finally:
|
481 |
gc.collect()
|
|
|
640 |
except gr.Error:
|
641 |
raise
|
642 |
except Exception as e:
|
643 |
+
error_message = f"推理过程异常: {str(e)}"
|
644 |
+
traceback_str = traceback.format_exc()
|
645 |
+
logger.error(error_message)
|
646 |
+
|
647 |
+
# 发送飞书通知
|
648 |
+
notification_message = format_error_for_notification("InferenceError", error_message, traceback_str)
|
649 |
+
feishu_notify(notification_message)
|
650 |
+
|
651 |
raise gr.Error(f"生成图像时发生意外错误: {str(e)}")
|
652 |
finally:
|
653 |
gc.collect()
|
|
|
892 |
except KeyboardInterrupt:
|
893 |
logger.info("接收到键盘中断,正在关闭...")
|
894 |
except Exception as e:
|
895 |
+
error_message = f"应用启动失败: {str(e)}"
|
896 |
+
traceback_str = traceback.format_exc()
|
897 |
+
logger.error(error_message)
|
898 |
+
|
899 |
+
# 发送飞书通知
|
900 |
+
notification_message = format_error_for_notification("ApplicationStartupError", error_message, traceback_str)
|
901 |
+
feishu_notify(notification_message)
|
902 |
+
|
903 |
raise
|
904 |
finally:
|
905 |
# 确保资源清理
|
906 |
try:
|
907 |
asyncio.run(cleanup_resources())
|
908 |
except Exception as e:
|
909 |
+
error_message = f"最终清理时出��: {str(e)}"
|
910 |
+
traceback_str = traceback.format_exc()
|
911 |
+
logger.error(error_message)
|
912 |
+
|
913 |
+
# 发送飞书通知
|
914 |
+
notification_message = format_error_for_notification("CleanupError", error_message, traceback_str)
|
915 |
+
feishu_notify(notification_message)
|
916 |
logger.info("应用已退出")
|
917 |
|
918 |
|