首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >打包流光应用程序并在windows上运行可执行文件

打包流光应用程序并在windows上运行可执行文件
EN

Stack Overflow用户
提问于 2021-09-27 19:19:17
回答 1查看 5.7K关注 0票数 5

这是我关于Stackoverflow的第一个问题。我希望我的问题是明确的,否则让我知道,并毫不犹豫地问我更多的细节。

我正试图为个人项目打包一个流光应用程序。我是在linux下开发的,但我必须在Windows上部署这个应用程序。我希望它是一个独立的可执行文件,一旦运行,就会打开浏览器选项卡来显示应用程序,并在选项卡关闭时退出。我想使用pynsist库来打包这个应用程序(已经用于另一个项目了,而且运行得很好)。

我遵循了这个讨论中的建议。它在ubuntu上运行得很好,而且很明显,在用pynsist打包这个应用程序之后,Windows上也是如此。“显然”是因为可执行程序运行,但没有打开浏览器选项卡来显示应用程序。

这是我的代码片段。

项目结构

代码语言:javascript
复制
|- installer.cfg
|- src
    |- main.py
    |- run_app.py

main.py

代码语言:javascript
复制
import streamlit as st

st.title("Test")
st.title("My first app deployed with Pynsist!")

run_app.py (托马斯K评论后的编辑2 )

代码语言:javascript
复制
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

编辑:,包括通过pip list发现的流光依赖关系

编辑2:添加了MarkupSafe作为Jinja2的依赖项

代码语言:javascript
复制
[Application]
name=Emporio Vestiario Dashboard
version=0.1.0
# How to lunch the app - this calls the 'main' function from the 'myapp' package:
entry_point=src.run_app:main
icon=resources/caritas-logo.ico

[Python]
version=3.8.10
bitness=64

[Include]
# Packages from PyPI that your application requires, one per line
# These must have wheels on PyPI:
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

查看Windows上的可执行输出,可以正确地打印当前工作目录,但没有打印其他输出(流光应用程序初始化消息或错误消息)。我试图打开浏览器并转到localhost:8501,但是我发现了连接错误。

对于如何使代码执行并自动打开浏览器选项卡,有什么提示吗?任何帮助都是非常感谢的!

编辑:--正如在对installer.cfg中最后一个包的注释中指出的,该应用程序(带有Jinja2依赖项)已正确安装在windows上,但在启动时,该应用程序仍然找不到Jinja2依赖项。这是回溯:

代码语言:javascript
复制
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.

编辑2:多亏了Thomas的有用提示,我想出了半个解决方案。该应用程序运行,并启动流光。

但。

这些是日志消息:

代码语言:javascript
复制
  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: 

该应用程序的执行似乎已经停止,因为它正在等待一些凭据。我发现这里可以添加一个.streamlit/credentials.toml,但是我不确定窗口上的确切位置。我还试图在--server.headless=false命令中显式地添加subprocess.run,但同样没有效果。

为什么应用程序不像Linux上那样自动启动?是否有一种方法来启动应用程序,而不需要用户进行额外的配置?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-10-18 19:30:24

编辑:在pynsist回购示例中添加了一个流显示示例。这里,您可以找到一个工作应用程序的极小且精化的示例(其中还包括巧妙的)。

原始答案

我终于开始工作了。在最后一次尝试中,我错误地设置了--server.headless=false,而它必须是true。我发现需要一个额外的标志到streamlit命令:--global.developmentMode=false。这就使得部署工作,即使我在流光配置中找不到对此配置的任何引用。

工作代码如下。

项目结构

代码语言:javascript
复制
|- wheels/
|- installer.cfg
|- src
    |- main.py
    |- run_app.py

main.py

代码语言:javascript
复制
import streamlit as st

st.title("Test")
st.title("My first app deployed with Pynsist!")

run_app.py

代码语言:javascript
复制
import os
import subprocess
import sys
import webbrowser

from src.config import EnvironmentalVariableNames as EnvVar, get_env


def main():

    # Getting path to python executable (full path of deployed python on Windows)
    executable = sys.executable

    # Open browser tab. May temporarily display error until streamlit server is started.
    webbrowser.open("http://localhost:8501")

    # Run streamlit server
    path_to_main = os.path.join(
        get_env(EnvVar.EMPORIO_VESTIARIO_DASHBOARD_WORKING_DIR), "src", "app.py"
    )
    result = subprocess.run(
        f"{executable} -m streamlit run {path_to_main} --server.headless=true --global.developmentMode=false",
        shell=True,
        capture_output=True,
        text=True,
    )

    # These are printed only when server is stopped.
    # NOTE: you have to manually stop streamlit server killing process.
    print(result.stdout)
    print(result.stderr)


if __name__ == "__main__":
    main()

一些注意事项:

  1. webbrowser.open需要在浏览器中自动打开一个新的选项卡,以显示流光应用程序。subprocess.run行只启动一个新的流光服务器。
  2. 正如我在评论中所指出的那样,一旦退出浏览器中的streamlit选项卡,streamlit服务器就仍然在那里并处于活动状态。您只需在地址栏中键入localhost:8501即可再次访问仪表板。如果在Windows应用程序图标上多次单击,则启动多个流光服务器。我试过在同一时间只有两个活动,他们没有表现出相互冲突的行为。例如,要阻止它们,您必须通过任务管理器手动结束任务。

installer.cfg

代码语言:javascript
复制
[Application]
name=Emporio Vestiario Dashboard
version=0.1.0
# How to lunch the app - this calls the 'main' function from the 'myapp' package:
entry_point=src.run_app:main
icon=resources/caritas-logo.ico

[Python]
version=3.8.10
bitness=64

[Include]
# Packages from PyPI that your application requires, one per line
# These must have wheels on PyPI:
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

extra_wheel_sources = ./wheels

注:blinker额外车轮是必需的。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69352179

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档