You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Azure Web App中Streamlit应用下载PPT触发AssertionError求助

问题分析

这个AssertionError: session with id 'xxx' is already connected!是Streamlit部署在Azure Web App时,WebSocket会话重复连接引发的异常,结合你的场景,触发核心原因有两点:

  1. 主线程长时间阻塞:点击Generate后,subprocess.run同步执行R脚本,Streamlit主线程被持续占用,导致和浏览器的WebSocket连接超时,浏览器自动发起重连,引发会话冲突。
  2. 会话状态未持久化:binary_appendix仅在Generate按钮的分支中定义,页面重新渲染(比如点击Download时)变量会丢失,加上特定季度生成的PPT数据量更大,进一步放大了会话状态异常问题。
规避与解决方案

1. 异步执行R脚本,避免主线程阻塞

将同步执行的R脚本改成异步线程执行,防止Streamlit主线程卡住导致WebSocket超时:

import subprocess
import threading
import time
import pandas as pd
from io import BytesIO

with col1:
    result = st.button("Generate")
if result:
    t1 = pd.Timestamp.now()
    st.write(f'Started at {str(pd.Timestamp.now().time())}')
    
    # 定义异步执行的函数
    def run_r_scripts(quarter):
        subprocess.run(["Rscript", "appendix_images_fcn.R", quarter])
        subprocess.run(["Rscript", "pla_fcn.R", quarter])
        
        prs = appendix_fcn.create_appendix(quarter)
        binary_appendix = BytesIO()
        prs.save(binary_appendix)
        # 将生成结果存入会话状态
        st.session_state['binary_appendix'] = binary_appendix
        st.session_state['generation_time'] = str(pd.Timestamp.now()-t1)
    
    # 启动后台线程执行
    threading.Thread(target=run_r_scripts, args=(quarter,), daemon=True).start()
    
    # 显示加载状态,等待生成完成
    with st.spinner("Generating PPT..."):
        while 'binary_appendix' not in st.session_state:
            time.sleep(0.5)
    st.write(f'generated in {st.session_state["generation_time"]}')

2. 用会话状态持久化二进制数据

把生成的PPT二进制数据存入st.session_state,避免页面重新渲染时变量丢失:

with col2:
    # 仅当生成完成后才显示下载按钮
    if 'binary_appendix' in st.session_state:
        current_time = str(pd.Timestamp.now())[2:-7].replace('-','').replace(' ','_').replace(':','')
        st.download_button(
            label='Download',
            data=st.session_state['binary_appendix'].getvalue(),
            file_name=f'Appendix_{quarter}_{current_time}.pptx'
        )
    else:
        st.info("请先点击'Generate'生成PPT后再下载")

3. 调整Azure Web App与Streamlit配置

  • 在Azure Portal进入你的Web App,在配置-应用程序设置中,将WEBSOCKET_ENABLED设为On,确保WebSocket连接正常。
  • 提升Web App的实例内存与CPU配额,针对数据量较大的季度,避免资源不足导致进程阻塞。
  • 在项目根目录的.streamlit/config.toml中添加WebSocket相关配置,增大消息大小限制:
[server]
enableWebsocketCompression = true
websocketMaxMessageSize = 52428800  # 50MB,可根据实际PPT大小调整

4. 额外优化:数据量预检查

针对特定季度数据过大的情况,在生成前添加数据规模检查,提前预警:

if result:
    # 自定义检查逻辑,比如读取该季度相关文件的大小
    def check_quarter_data_size(quarter):
        # 示例:读取生成所需的数据源文件大小
        import os
        data_path = f"data_{quarter}.csv"
        return os.path.getsize(data_path) if os.path.exists(data_path) else 0
    
    data_size = check_quarter_data_size(quarter)
    if data_size > 100 * 1024 * 1024:  # 100MB阈值
        st.warning("该季度数据量较大,生成过程可能耗时较长,请耐心等待")
    # 后续生成逻辑...

内容的提问来源于stack exchange,提问作者frank

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 07:25:37