Add final report download button (#329)

* fix(app): 改进应用健康检查机制并更新默认配置

添加专用的健康检查路径和代理配置,重构健康检查URL构建逻辑
增加健康检查失败时的日志记录
延长应用启动等待时间至90秒

* style(templates): 统一CSS选择器缩进格式并修复空格问题

* feat(报告下载): 实现报告文件下载功能并增强任务状态管理

- 在ReportAgent中修改generate_report返回包含文件路径的字典
- 在ReportTask中添加文件路径相关字段
- 新增/download接口用于下载报告文件
- 在前端添加下载按钮及相关控制逻辑
- 完善任务状态显示,增加文件路径信息

* feat(report): 添加报告下载功能并优化状态管理

- 在ReportAgent中返回报告文件保存路径信息
- 新增Flask接口/download/<task_id>用于下载报告文件
- 在前端添加下载按钮及相关控制逻辑
- 修复报告生成状态重置问题
- 优化健康检查URL构建和代理设置
- 统一CSS样式中的空格和缩进

---------

Co-authored-by: HKLHaoBin <we3q@qq.com>
Co-authored-by: Zhang Yuxiang <51037789+NTFago@users.noreply.github.com>
This commit is contained in:
BaiFu
2025-11-13 00:48:52 +08:00
committed by GitHub
parent 516f37bd25
commit f004407f4b
5 changed files with 358 additions and 69 deletions
+26 -11
View File
@@ -656,6 +656,14 @@ def stop_streamlit_app(app_name):
except Exception as e:
return False, f"停止失败: {str(e)}"
HEALTHCHECK_PATH = "/_stcore/health"
HEALTHCHECK_PROXIES = {'http': None, 'https': None}
def _build_healthcheck_url(port):
return f"http://127.0.0.1:{port}{HEALTHCHECK_PATH}"
def check_app_status():
"""检查应用状态"""
for app_name, info in processes.items():
@@ -663,21 +671,24 @@ def check_app_status():
if info['process'].poll() is None:
# 进程仍在运行,检查端口是否可访问
try:
response = requests.get(f"http://localhost:{info['port']}", timeout=2)
response = requests.get(
_build_healthcheck_url(info['port']),
timeout=2,
proxies=HEALTHCHECK_PROXIES
)
if response.status_code == 200:
info['status'] = 'running'
else:
info['status'] = 'starting'
except requests.exceptions.RequestException:
info['status'] = 'starting'
except Exception:
except Exception as exc:
logger.warning(f"{app_name} 健康检查失败: {exc}")
info['status'] = 'starting'
else:
# 进程已结束
info['process'] = None
info['status'] = 'stopped'
def wait_for_app_startup(app_name, max_wait_time=30):
def wait_for_app_startup(app_name, max_wait_time=90):
"""等待应用启动完成"""
import time
start_time = time.time()
@@ -690,15 +701,19 @@ def wait_for_app_startup(app_name, max_wait_time=30):
return False, "进程启动失败"
try:
response = requests.get(f"http://localhost:{info['port']}", timeout=2)
response = requests.get(
_build_healthcheck_url(info['port']),
timeout=2,
proxies=HEALTHCHECK_PROXIES
)
if response.status_code == 200:
info['status'] = 'running'
return True, "启动成功"
except:
pass
except Exception as exc:
logger.warning(f"{app_name} 健康检查失败: {exc}")
time.sleep(1)
return False, "启动超时"
def cleanup_processes():
@@ -1042,4 +1057,4 @@ if __name__ == '__main__':
logger.info("\n正在关闭应用...")
cleanup_processes()