Troubles using pyinstaller with streamlit

I have a fairly complex streamlit app I’m trying to package up into a single .exe file with pyinstaller.

I’m using the instructions here.

I go through the steps, and when I try to run the run.exe I get the following error…

(streamlit-pyinstaller) C:\Users\<username>\Documents\streamlit-project\dist>run.exe

  You can now view your Streamlit app in your browser.

  Local URL: http://localhost:8501
  Network URL: http://10.x.x.112:8501

2024-09-26 15:02:18.608 Uncaught exception in write_error
Traceback (most recent call last):
  File "streamlit\web\server\routes.py", line 69, in validate_absolute_path
  File "tornado\web.py", line 2900, in validate_absolute_path
tornado.web.HTTPError: HTTP 404: Not Found

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "tornado\web.py", line 1790, in _execute
  File "tornado\web.py", line 2688, in get
  File "streamlit\web\server\routes.py", line 84, in validate_absolute_path
  File "tornado\web.py", line 2900, in validate_absolute_path
tornado.web.HTTPError: HTTP 404: Not Found

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "tornado\web.py", line 1298, in send_error
  File "streamlit\web\server\routes.py", line 91, in write_error
  File "tornado\web.py", line 944, in render
  File "tornado\web.py", line 1090, in render_string
  File "tornado\template.py", line 446, in load
  File "tornado\template.py", line 476, in _create_template
FileNotFoundError: [Errno 2] No such file or directory: 'C:\\Users\\<username>\\AppData\\Local\\Temp\\_MEI466842\\streamlit\\static\\index.html'

I have tried with both the default run.spec, and the following custom spec.

I assume it has to do with the static index.html for tornado, found in …

c:\Users\<username>\Documents\venv\streamlit-pyinstaller\Lib\site-packages\tornado\test\static\dir\index.html

…but I’m not sure this is the problem, nor if adding the index.html to datas=[] in run.spec is the right thing to do (since, I think, that copies the file to streamlit’s root and I’m not sure that will work :D)

Does anyone have an idea how to fix this?

run.spec

# -*- mode: python ; coding: utf-8 -*-

a = Analysis(
    ['run.py'],

    pathex=[
    'C:\\Users\\<username>\\Documents\\cdr-streamlit',
    'C:\\Program Files\\Python312\\python312.zip',
    'C:\\Program Files\\Python312\\DLLs',
    'C:\\Program Files\\Python312\\Lib',
    'C:\\Program Files\\Python312',
    'C:\\Users\\<username>\\Documents\\venv\\streamlit-pyinstaller',
    'C:\\Users\\<username>\\Documents\\venv\\streamlit-pyinstaller\\Lib\\site-packages',
    'C:\\Users\\<username>\\AppData\\Roaming\\Python', 
    'C:\\Users\\<username>\\AppData\\Roaming\\Python\\Python312\\site-packages'
],
    
    binaries=[],
    datas=[],
    hiddenimports=['streamlit', 'tornado'],
    hookspath=['./hooks'],
    hooksconfig={},
    runtime_hooks=[],
    excludes=[],
    noarchive=False,
    optimize=0,
)
pyz = PYZ(a.pure)

exe = EXE(
    pyz,
    a.scripts,
    a.binaries,
    a.datas,
    [],
    name='run',
    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,
)