Streamlit app

28 views
Skip to first unread message

Daniel Juschus

unread,
Mar 29, 2024, 9:06:20 AMMar 29
to PyInstaller
Hello,

I just cannot manage to package a simple Streamlit app (a library for creating browser-based GUIs). I have read through all the material on the Pyinstaller website and the Github wiki.
 
This is my main.py:

import streamlit as st

st.text("This program is running")

and this is my wrapper.py:

import subprocess
from pathlib import Path
import sys

def resource_path(relative_path):
try:
base_path = Path(sys._MEIPASS)
except AttributeError:
return relative_path
return base_path.joinpath(relative_path).as_posix()

main_script_path = resource_path("main.py")

with open('streamlit_output.txt', 'w') as f_out, open('streamlit_error.txt', 'w') as f_err:
subprocess.run(f'streamlit run "{main_script_path}"',
stdout=f_out, stderr=f_err, check=True, shell=True)


Running this wrapper locally works. 

To package it with Pyinstaller I first run pyi-makespec --onedir -w --additional-hooks-dir=hooks --add-data "main_st.py;." --hidden-import=streamlit --debug=all wrapper_st.py.

My hook-streamlit.py looks like this:

from PyInstaller.utils.hooks import copy_metadata, collect_submodules

datas = copy_metadata("streamlit")
hiddenimports = collect_submodules('streamlit')

I then modify the spec file datas section as follows (some people online said that this was necessary):

a = Analysis(
['wrapper_st.py'],
pathex=[],
binaries=[],
datas=[('main_st.py', '.'),
('C:/Users/jusc_da/venvs/airfucs-calc-311/Lib/site-packages/altair/vegalite/v5/schema', './altair/vegalite/v5/schema'),
('C:/Users/jusc_da/venvs/airfucs-calc-311/Lib/site-packages/streamlit/static', './streamlit/static')],
...

Finally I build the exe by running pyinstaller wrapper_st.spec --clean --noconfirm.

When double clicking the resulting exe, nothing happens. The streamlit_error.txt file contains:

'streamlit' is not recognized as an internal or external command,
operable program or batch file.


What am I doing wrong?




bwoodsend

unread,
Mar 29, 2024, 6:32:35 PMMar 29
to PyInstaller

Never try to run a Python command line entry point from a subprocess. Even without PyInstaller involved, there’s no guarantee that it’ll be findable. Lookup what the entry point does (in this case calling from streamlit.web.cli.main() and put that in your code instead.

Daniel Juschus

unread,
Apr 1, 2024, 11:54:45 AMApr 1
to PyInstaller
Alright, thanks!

I have written a new wrapper_cli.py:

from streamlit.web.cli import main
import sys

sys.argv.append('run')
sys.argv.append('main_st.py')

main()

This works just fine locally. 

When I package it the same way, and then run it by double clicking, nothing happens. When I run it through the terminal as .\wrapper_cli.py, a browser window opens, strangely pointing to localhost:3000, with the browser showing "localhost refused to connect".

Any idea how I can start debugging this?

bwoodsend

unread,
Apr 2, 2024, 1:26:08 PMApr 2
to PyInstaller

sys.argv.append(‘main_st.py’)

Arhhh! See standard reply.

Reply all
Reply to author
Forward
0 new messages