使用pynsist打包Streamlit应用为Windows独立可执行文件的启动问题求助
这是我在Stack Overflow的首个提问,若描述存在不清晰的地方,欢迎随时询问更多细节。
我正在为个人项目打包Streamlit应用,开发环境为Linux,但需要部署到Windows系统,目标是生成独立可执行文件,运行后自动打开浏览器标签页展示应用,关闭标签页后程序自动退出。我计划使用pynsist库完成打包(该库我在其他项目中使用过,运行表现稳定)。
我参照相关讨论的建议操作,在Ubuntu上运行正常,用pynsist打包后在Windows上看似能正常运行,实际是可执行文件启动后,没有自动打开浏览器标签页展示应用,手动访问localhost:8501也报连接错误,也没有输出Streamlit初始化日志或报错信息,仅正确打印了当前工作目录。
相关代码与配置
项目结构
|- installer.cfg |- src |- main.py |- run_app.py
main.py
import streamlit as st st.title("Test") st.title("My first app deployed with Pynsist!")
run_app.py(经Thomas K评论后更新的EDIT 2版本)
import os import subprocess import sys from src.config import EnvironmentalVariableNames as EnvVar, get_env def main(): executable = sys.executable result = subprocess.run( f"{executable} -m streamlit run {os.path.join(get_env(EnvVar.EMPORIO_VESTIARIO_DASHBOARD_WORKING_DIR), 'src', 'main.py')}", shell=True, capture_output=True, text=True, ) if __name__ == "__main__": main()
其中EMPORIO_VESTIARIO_DASHBOARD_WORKING_DIR是环境变量,用于适配Linux和Windows双系统,Windows下指向程序安装目录。
installer.cfg(pynsist配置文件,已通过pip list补全Streamlit依赖,EDIT 2新增Jinja2的依赖MarkupSafe)
[Application] name=Emporio Vestiario Dashboard version=0.1.0 # 应用启动入口:调用src.run_app模块的main函数 entry_point=src.run_app:main icon=resources/caritas-logo.ico [Python] version=3.8.10 bitness=64 [Include] # 应用依赖的PyPI包,每行一个,必须在PyPI上有对应的wheel包 pypi_wheels = altair==4.1.0 astor==0.8.1 attrs==21.2.0 backcall==0.2.0 backports.zoneinfo==0.2.1 base58==2.1.0 bleach==4.1.0 blinker==1.4 cachetools==4.2.2 certifi==2021.5.30 cffi==1.14.6 charset-normalizer==2.0.6 click==7.1.2 decorator==5.1.0 defusedxml==0.7.1 distlib==0.3.3 entrypoints==0.3 idna==3.2 jsonschema==3.2.0 mistune==0.8.4 mypy-extensions==0.4.3 numpy==1.21.1 packaging==21.0 pandas==1.3.3 pandocfilters==1.5.0 parso==0.8.2 pillow==8.3.2 platformdirs==2.4.0 prompt-toolkit==3.0.20 protobuf==3.18.0 pyarrow==5.0.0 pycparser==2.20 pydeck==0.7.0 pyparsing==2.4.7 pyrsistent==0.18.0 python-dateutil==2.8.2 pytz==2021.1 requests==2.26.0 requests-download==0.1.2 send2trash==1.8.0 setuptools==57.0.0 six==1.14.0 smmap==4.0.0 streamlit==0.89.0 terminado==0.12.1 testpath==0.5.0 toml==0.10.2 tomli==1.2.1 toolz==0.11.1 tornado==6.1 traitlets==5.1.0 typing-extensions==3.10.0.2 tzlocal==3.0 urllib3==1.26.7 validators==0.18.2 Jinja2==3.0.1 MarkupSafe==2.0.1
排查进展
EDIT1
即便在installer.cfg中加入了Jinja2依赖,Windows安装后启动仍报Jinja2缺失错误,报错栈如下:
Traceback (most recent call last): File "Emporio_Vestiario_Dashboard.launch.pyw", line 34, in <module> from src.run_app import main File "C:\Users\tantardini\develop\caritas\pkgs\src\run_app.py", line 6, in <module> import streamlit File "C:\Users\tantardini\develop\caritas\pkgs\streamlit\__init__.py", line 75, in <module> from streamlit.delta_generator import DeltaGenerator as _DeltaGenerator File "C:\Users\tantardini\develop\caritas\pkgs\streamlit\delta_generator.py", line 70, in <module> from streamlit.elements.arrow import ArrowMixin File "C:\Users\tantardini\develop\caritas\pkgs\streamlit\elements\arrow.py", line 20, in <module> from pandas.io.formats.style import Styler File "C:\Users\tantardini\develop\caritas\pkgs\pandas\io\formats\style.py", line 49, in <module> jinja2 = import_optional_dependency("jinja2", extra="DataFrame.style requires jinja2.") File "C:\Users\tantardini\develop\caritas\pkgs\pandas\compat\_optional.py", line 118, in import_optional_dependency raise ImportError(msg) from None ImportError: Missing optional dependency 'Jinja2'. DataFrame.style requires jinja2. Use pip or conda to install Jinja2.
EDIT2
经Thomas K提示后解决了依赖问题,程序能启动Streamlit,但又出现新问题:启动日志显示Streamlit等待邮箱输入,程序卡住,日志还出现CORS和XSRF配置警告、credentials报错,日志如下:
Welcome to Streamlit! If you're one of our development partners or you're interested in getting personal technical support or Streamlit updates, please enter your email address below. Otherwise, you may leave the field blank. Email: 2021-10-11 20:56:53.202 WARNING streamlit.config: Warning: the config option 'server.enableCORS=false' is not compatible with 'server.enableXsrfProtection=true'. As a result, 'server.enableCORS' is being overridden to 'true'. More information: In order to protect against CSRF attacks, we send a cookie with each request. To do so, we must specify allowable origins, which places a restriction on cross-origin resource sharing. If cross origin resource sharing is required, please disable server.enableXsrfProtection. 2021-10-11 20:56:53.202 DEBUG streamlit.logger: Initialized tornado logs 2021-10-11 20:56:53.202 ERROR streamlit.credentials:
我尝试在subprocess.run命令中添加--server.headless=false参数没有效果,查到可以添加.streamlit/credentials.toml文件但不清楚Windows下的存放路径。
待解答问题
为什么Windows下不能像Linux一样自动启动应用?有没有办法无需用户额外配置就能直接启动应用?
内容的提问来源于stack exchange,提问作者mattiatantardini

