Thanks Simon! I have also raised my issue in your Github. Pls give it a glance when you have time.
@hmasdev solution worked for me, with a few notes:
-
streamlit.cli is now streamlit.web.cli
-
The flag_options change to the main_run_cl_Explicit function was necessary
-
Worked fine with Pyinstaller 5.4.1
-
Dragging the exe out of dist was preferable to copying everything into dist
Hi all!
This solution also works for me, however I donât go through âmain_run_cl_Explicitâ.
In my run_main.py I just used these lines of codes.
import streamlit.web.cli as stcli
import sys
def streamlit_run():
sys.argv=["streamlit", "run", "main.py", "--global.developmentMode=false"]
sys.exit(stcli.main())
if __name__ == "__main__":
streamlit_run()
I have another problem, how to integrate St-Aggrid with Pysintaller???
Is it going to work if my main streamlit file is named âmain_streamlit.pyâ instead of âmain.pyâ?
with the change " streamlit.cli._main_run_clExplicit(âmain_streamlit.pyâ, âstreamlit runâ)
" inside run_main.py file.
Hi @orudne , @kevinlinxc
I have tried these 5 stepsâŠHowever while running the 5th step, Iâm getting the follow error:
399 INFO: PyInstaller: 5.7.0
400 INFO: Python: 3.8.5 (conda)
401 INFO: Platform: Windows-10-10.0.19041-SP0
option(s) not allowed:
âonedir/âonefile
âadditional-hooks-dir
makespec options not valid when a .spec file is given
When I use --onedir option in the same command, then it runs fine but the 404 error still occurs when I click on the exe fileâŠ
Can anyone help please?
Dear all.
Iâm new on this forum, and sorry If I make some mistakes when asking something.
Iâve tried this method to convert simple main.py (as in your example) to exe, procedure was without errors, but when I double clicked on run_main.exe, cmd window appeared for a short, and then disapear and nothing happend after it. What could be a problem?
Also, I donât know exactly what I must do in this part (picture bellow):
what means add folowing lines to cli.py, is that mean to open cli.py and add in it this line:
${YOUR_CONDA_ENV}/lib/site-packages/streamlit/cli.py
And where to add it before or after :
def _main_run_clExplicit(file, command_line, args=):
streamlit._is_running_with_streamlit = True
bootstrap.run(file, command_line, args)
thx in advance,
best regards,
Adnan
You have to copy the function code inside the cli.py file. Default cli.py doesnât contain the code for function â_main_run_clExplicitâ so it needs to be added manually.
I create a repo to explain the step by step to solve this. And in few hours Iâm publishing a video! Give your like and GH star!
I just create a repo with Really minimal Streamlit use case following your step-by-step
Thinking on you I create a repo with Really minimal Streamlit use case! Give a star! The video came out of the oven in a few hours. Se vocĂȘ quiser pode clonar o repo e seguir o passo a passo do README antes mesmo de eu publicar o video que serĂĄ live no twitchJVCSS and published on youtubeJVCSS
After following steps posted by @hmasdev and @kevinlinxc, I managed to get it working. Thought it would be worthwhile to post some changes I had to make to get this working, especially with newer versions floating around.
Iâm working with Streamlit 1.17.0 (boy have things changed a lot), as well as Pyinstaller 5.7.0. I also use Pipenv, but that shouldnât really matter here.
- Still need to create
run_main.py
, but we no longer need to create_main_run_clExplicit
, as we can callbootstrap.run()
directly with the proper flags now.
import streamlit.web.bootstrap
if __name__ == "__main__":
streamlit.web.bootstrap.run(
"./main.py",
"streamlit run",
[],
{"_is_running_with_streamlit": True},
)
- Create
./hooks/hook-streamlit.py
as shown - Create
./.streamlit/config.toml
as shown - To create the spec file, I used
pyi-makespec --onefile --additional-hooks-dir=./hooks run_main.py
instead ofpyinstaller --onefile ...
, just because itâs quite a bit faster and we donât care about the binary compiled bypyinstaller
at this point anyways. After that, updaterun_main.spec
as shown. - The final executable can then be compiled using
pyinstaller run_main.spec --clean
(this avoids the invalid makespec options other people have been seeing) - I agree with @kevinlinxc here, it is much simpler to lift the resultant binary out from
./dist
into the working directory to run
Hopefully this helps/updates this a bit!
Edit:
After some tweaking, I managed to get this to compile everything into a true single binary, where you donât need to keep the executable in the repository for it to run. To do this, I place my streamlit app code (i.e. main.py
with any st.write()
stuff) into a subdirectory called ./application
.
- We still need to create
run_main.py
, but we add in the config we previously set in./.streamlit/config.toml
directly and load it in
import os
import streamlit.web.bootstrap
if __name__ == "__main__":
os.chdir(os.path.dirname(__file__))
flag_options = {
"server.port": 8501,
"global.developmentMode": False,
}
streamlit.web.bootstrap.load_config_options(flag_options=flag_options)
flag_options["_is_running_with_streamlit"] = True
streamlit.web.bootstrap.run(
"./application/main.py",
"streamlit run",
[],
flag_options,
)
- We still must create
./hooks/hook-streamlit.py
as previously mentioned - We do not need to create
./.streamlit/config.toml
anymore. It shouldnât hurt if itâs there, but the config will not be used - Create specfile using
pyi-makespec --onefile --additional-hooks-dir=./hooks run_main.py
(orpyinstaller
, I just tend to preferpyi-makespec
) and update it with the following:
datas=[
(
"<path to lib>/Lib/site-packages/altair/vegalite/v4/schema/vega-lite-schema.json",
"./altair/vegalite/v4/schema/"
),
(
"<path to lib>/Lib/site-packages/streamlit/static",
"./streamlit/static"
),
(
"<path to app code>/application",
"./application"
)
],
hiddenimports=[
"streamlit"
],
The last entry to datas
is important, as it tells pyinstaller to bundle in all of the streamlit app code.
- Compile the final executable with
pyinstaller run_main.spec --clean
- The final executable can be run anywhere, no need to move it to any specific location!
Hey @charlesmyu , tried the solution which you have suggested. Followed every but of it but when I run the final exectuable I get an error something like this
ModuleNotFoundError: No module named âstreamlit.runtime.scriptrunner.magic_funcsâ.
File "streamlit\runtime\scriptrunner\script_runner.py", line 565, in _run_scriptFile "C:\Users\NikhilRanade\AppData\Local\Temp\_MEI275882\application\main.py", line 1, in <module>
import streamlit as st
Attaching screenshot for the reference. Any help would be appreciated on this
I was in the same boat but think I have it worked out. In your ârun_main.pyâ file - include an import streamlit.runtime.scriptrunner.magic_funcs
line. Not sure why plain import streamlit
doesnât work but this worked for me.
Thanks @littletuna it worked for me also. But I have several other imports in my script for which I am facing below error when I run the .exe file.
No such component directory: âC:\Users\NIKHIL~2\AppData\Local\Temp_MEI211242\streamlit_option_menu\frontend\distâ
Do we need to specify these imports somewhere? Thanks for the help in advance.
@Nikhil_Ranade Are you sure you have the hooks created correctly, and the specfile defined with the correct datas
? Those would be my first guess, usually any import errors I run into stem from issues with one of those two things
Below is my hook-streamlit.py file and the spec file respectively. Is there something I might be missing here? Thanks for the help in advance.
from PyInstaller.utils.hooks import copy_metadata
datas = copy_metadata('streamlit')
# -*- mode: python ; coding: utf-8 -*-
block_cipher = None
a = Analysis(
['run_main.py'],
pathex=["C:/Users/NikhilRanade/AppData/Local/Programs/Python/Python38/Lib/site-packages"],
binaries=[],
datas=[ (
"C:/Users/NikhilRanade/AppData/Local/Programs/Python/Python38/Lib/site-packages/altair/vegalite/v4/schema/vega-lite-schema.json",
"./altair/vegalite/v4/schema/"
),
(
"C:/Users/NikhilRanade/AppData/Local/Programs/Python/Python38/Lib/site-packages/streamlit/static",
"./streamlit/static"
),
(
"C:/Users/NikhilRanade/Desktop/Nikhil/EXE_ShareMon/application",
"./application"
)],
hiddenimports=["streamlit"],
hookspath=['./hooks'],
hooksconfig={},
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher,
noarchive=False,
)
pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher)
exe = EXE(
pyz,
a.scripts,
a.binaries,
a.zipfiles,
a.datas,
[],
name='run_main',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
upx_exclude=[],
runtime_tmpdir=None,
console=True,
disable_windowed_traceback=False,
argv_emulation=False,
target_arch=None,
codesign_identity=None,
entitlements_file=None,
)
@Nikhil_Ranade Ah, I see - I didnât realize streamlit-options-menu
was an additional package. Try adding it to hiddenimports
(i.e. hiddenimports=["streamlit", "streamlit-options-menu"]
and it should work!
Sometimes pyinstaller
needs some help to recognize the imports. Whenever I get an import error, the first thing I try is adding it to hiddenimports
, which forces pyinstaller
to look for the package and bundle it in.
Dear @charlesmyu ,
Thank for your previous answers. I am trying to find a solution for turning my app into an executable but as I am in a corporate context, IT donât give us user permission. I built my project using a virtual environment and followed all the steps but I still have an issue. I have a logo used by my application and when I run I have an error because it canât seem to find it. Is there something I should add in datas with makespecs please ?
@charlesmyu , tried that as well but it did not work
# -*- mode: python ; coding: utf-8 -*-
block_cipher = None
a = Analysis(
['run_main.py'],
pathex=["C:/Users/NikhilRanade/AppData/Local/Programs/Python/Python38/Lib/site-packages"],
binaries=[],
datas=[ (
"C:/Users/NikhilRanade/AppData/Local/Programs/Python/Python38/Lib/site-packages/altair/vegalite/v4/schema/vega-lite-schema.json",
"./altair/vegalite/v4/schema/"
),
(
"C:/Users/NikhilRanade/AppData/Local/Programs/Python/Python38/Lib/site-packages/streamlit/static",
"./streamlit/static"
),
(
"C:/Users/NikhilRanade/Desktop/Nikhil/EXE_ShareMon/application",
"./application"
)],
hiddenimports=["streamlit","snowflake","snowflake-connector-python","streamlit_option_menu"],
hookspath=['./hooks'],
hooksconfig={},
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher,
noarchive=False,
)
pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher)
exe = EXE(
pyz,
a.scripts,
a.binaries,
a.zipfiles,
a.datas,
[],
name='run_main',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
upx_exclude=[],
runtime_tmpdir=None,
console=True,
disable_windowed_traceback=False,
argv_emulation=False,
target_arch=None,
codesign_identity=None,
entitlements_file=None,
)
Also tried something like this but no luck here as well
import sys
sys.path.insert(1, "C:/Users/NikhilRanade/AppData/Local/Programs/Python/Python38/Lib/site-packages/streamlit_option_menu")
from streamlit_option_menu import option_menu
Hello everybody, i have a problem with âon_hover_tabsâ
in my main.py i have
from st_on_hover_tabs import on_hover_tabs
import streamlit as st
in my run_main.py ihave
import streamlit.web.cli as stcli
import sys
import streamlit.runtime.scriptrunner.magic_funcs
def streamlit_run():
sys.argv=["streamlit", "run", "main.py", "--global.developmentMode=false"]
sys.exit(stcli.main())
if __name__ == "__main__":
streamlit_run()
in my run_main.spec
# -*- mode: python ; coding: utf-8 -*-
block_cipher = None
a = Analysis(
['run_main.py'],
pathex=[],
binaries=[],
datas=[
(
"C:/SC/Python39/Lib/site-packages/altair/vegalite/v4/schema/vega-lite-schema.json",
"./altair/vegalite/v4/schema/"
),
(
"C:/SC/Python39/Lib/site-packages/streamlit/static",
"./streamlit/static"
),
(
"C:/SC/Python39/Lib/site-packages/st_on_hover_tabs/frontend/build/static",
"./st_on_hover_tabs/static"
),
(
"C:/SC/Pycharm_Project/Tools_database",
".application"
),
],
hiddenimports=[
"streamlit"
],
hookspath=['./hooks'],
hooksconfig={},
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher,
noarchive=False,
)
pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher)
exe = EXE(
pyz,
a.scripts,
a.binaries,
a.zipfiles,
a.datas,
[],
name='run_main',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
upx_exclude=[],
runtime_tmpdir=None,
console=True,
disable_windowed_traceback=False,
argv_emulation=False,
target_arch=None,
codesign_identity=None,
entitlements_file=None,
icon=['style\\pstudio.ico'],
)
I have an error when i launch my exe file
ImportError: cannot import name 'on_hover_tabs' from 'st_on_hover_tabs' (unknown location)
Traceback:
File "streamlit\runtime\scriptrunner\script_runner.py", line 565, in _run_scriptFile "C:\SC\Pycharm_Project\Tools_database\dist\main.py", line 3, in <module>
from st_on_hover_tabs import on_hover_tabs
Thanks in advance for your help.