使用PyInstaller打包Streamlit应用时出现SessionInfo相关错误
Streamlit应用PyInstaller打包后UI操作触发错误的解决方法
问题详情
本地执行streamlit run myapp.py时应用完全正常,但用PyInstaller打包为exe后,运行时弹出错误提示Bad message format, Tried to use SessionInfo before it was initialized,控制台具体报错:
ERROR:asyncio:Exception in callback AppSession._on_scriptrunner_event.<locals>.<lambda>() at streamlit\runtime\app_session.py:473 handle: <Handle AppSession._on_scriptrunner_event.<locals>.<lambda>() at streamlit\runtime\app_session.py:473> Traceback (most recent call last): File "asyncio\events.py", line 81, in _run File "streamlit\runtime\app_session.py", line 473, in <lambda> lambda: self._handle_scriptrunner_event_on_event_loop( File "streamlit\runtime\app_session.py", line 543, in _handle_scriptrunner_event_on_event_loop self._create_new_session_message(page_script_hash) File "streamlit\runtime\app_session.py", line 660, in _create_new_session_message imsg.is_hello = self._script_data.is_hello TypeError: an integer is required (got type str)
涉及的app_session.py代码片段:
""" This is generally called from the sender ScriptRunner's script thread. We forward the event on to _handle_scriptrunner_event_on_event_loop, which will be called on the main thread. """ self._event_loop.call_soon_threadsafe( lambda: self._handle_scriptrunner_event_on_event_loop( sender, event, forward_msg, exception, client_state, page_script_hash ) )
每次修改UI都会触发相同错误,但应用核心功能仍可正常使用。打包用的.spec文件内容如下:
# -*- mode: python ; coding: utf-8 -*- a = Analysis( ['myapp.py'], pathex=[], binaries=[], datas=[ ( "./venv/Lib/site-packages/altair/vegalite/v5/schema/vega-lite-schema.json", "./altair/vegalite/v5/schema/" ), ( "./venv/Lib/site-packages/", "." ), ( "./*.py", "." ), ], hiddenimports=[ "streamlit", "streamlit-extras" ], hookspath=['./hooks'], hooksconfig={}, runtime_hooks=[], excludes=[], noarchive=False, ) pyz = PYZ(a.pure) exe = EXE( pyz, a.scripts, [], exclude_binaries=True, name='myapp', debug=True, bootloader_ignore_signals=False, strip=False, upx=True, console=True, disable_windowed_traceback=False, argv_emulation=False, target_arch=None, codesign_identity=None, entitlements_file=None, ) coll = COLLECT( exe, a.binaries, a.datas, strip=False, upx=True, upx_exclude=[], name='my_app', )
解决步骤
1. 修正.spec文件的资源配置
你的.spec中把整个site-packages复制到根目录,导致Streamlit模块路径混乱,覆盖了内部类型定义文件。修改datas为只复制必要资源:
datas=[ # 保留Altair的schema文件 ("./venv/Lib/site-packages/altair/vegalite/v5/schema/vega-lite-schema.json", "./altair/vegalite/v5/schema/"), # 单独复制Streamlit模块到对应路径 ("./venv/Lib/site-packages/streamlit", "./streamlit"), # 复制自身脚本文件 ("./*.py", "."), ],
2. 补充必要的隐藏导入
显式声明Streamlit的核心内部模块,避免打包时遗漏:
hiddenimports=[ "streamlit", "streamlit-extras", "streamlit.runtime.scriptrunner.script_runner", "streamlit.runtime.app_session", "asyncio", ], # 若无自定义钩子,移除hookspath配置或留空 hookspath=[],
3. 关闭UPX压缩
UPX压缩会破坏Streamlit的二进制模块或字节码结构,导致类型识别错误。在EXE和COLLECT段将upx=True改为upx=False:
exe = EXE( pyz, a.scripts, [], exclude_binaries=True, name='myapp', debug=True, bootloader_ignore_signals=False, strip=False, upx=False, # 关闭UPX console=True, disable_windowed_traceback=False, argv_emulation=False, target_arch=None, codesign_identity=None, entitlements_file=None, ) coll = COLLECT( exe, a.binaries, a.datas, strip=False, upx=False, # 关闭UPX upx_exclude=[], name='my_app', )
4. 临时修复Streamlit类型转换问题(可选)
若上述方法无效,可临时修改虚拟环境中的streamlit/runtime/app_session.py第660行,强制转换类型:
# 原代码 imsg.is_hello = self._script_data.is_hello # 修改为 imsg.is_hello = int(self._script_data.is_hello)
修改后重新打包即可,后续Streamlit版本更新后可能无需此操作。
内容的提问来源于stack exchange,提问作者String
相关产品推荐
相关产品推荐

