pyenv virtualenv <version> .<env-name>
# or
python -m venv .<env-name>
# THE DOT IS IMPORTANT!
pyenv activate <env-name>
# or
.<env-name>\\Scripts\\activate.bat
python --version
pyenv deactivate
# or
.<env-name>\\Scripts\\deactivate.bat
# You can use the latest version
pip install streamlit pyinstaller
echo > app.py
echo > run_app.py
- app.py:
import streamlit as st
if __name__ == '__main__':
st.header("Hello, World!")
- run_app.py
from streamlit.web import cli
# This import path depends on your Streamlit version
if __name__ == '__main__':
cli._main_run_clExplicit('app.py', args=['run'])
# We will CREATE this function inside our Streamlit framework
In the version we are using, it is located at: .env\Lib\site-packages\streamlit\web\cli.py
# ... def main(log_level="info"):
# [...]
# You can use any name you prefer as long as it starts with an underscore
def _main_run_clExplicit(file, is_hello, args=[], flag_options={}):
bootstrap.run(file, is_hello, args, flag_options)
# ...if __name__ == "__main__":
# ... main()
- .\hooks\hook-streamlit.py
from PyInstaller.utils.hooks import copy_metadata
datas = copy_metadata('streamlit')
Run the following command to create the first run_app.spec file. Note that if you are using auto-py-to-exe, you can't edit spec files here; you should edit them from the interface in the advanced options.
pyinstaller --onefile --additional-hooks-dir=./hooks run_app.py --clean
# --onefile: Create a single output file
# --clean: Delete cache and remove temporary files before building
# --additional-hooks-dir: An additional path to search for hooks. This option can be used multiple times.
You can add these files to your project's root and the output folder, or just the output folder.
- .streamlit\config.toml
[global]
developmentMode = false
[server]
port = 8502
xcopy /s /e .streamlit output/.streamlit
# Select D = directory
copy app.py output/app.py
...
a = Analysis(
...
datas=[
(".env/Lib/site-packages/altair/vegalite/v5/schema/vega-lite-schema.json",
"./altair/vegalite/v5/schema/"),
(".env/Lib/site-packages/streamlit/static",
"./streamlit/static"),
(".env/Lib/site-packages/streamlit/runtime",
"./streamlit/runtime"),
]
...
)
...
#
# this path pair should be in that way
# but I believe it is because we add the tuple as this templete
# (absolut_path, parent_path)
# so for files that is in the root of `Lib/site-packages`
# We can add only the dot as parent
# i.e: (".envir/Lib/site-packages/wmi.py",".")
# for folders the behaviour is the same
pyinstaller run_app.spec --clean
Huge Thanks To: hmasdevI'm organizing the solution from hmasdev in the Streamlit Forum