Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PyInstaller error when executing Plotly Dash .exec file

I am trying to create a .exe file to run a python dashboard created with Plotly Dash. Once I create the file with PyInstaller and try to run it, I get this error:

Traceback (most recent call last):
  File "app.py", line 2, in <module>
  File "<frozen importlib._bootstrap>", line 983, in _find_and_load
  File "<frozen importlib._bootstrap>", line 967, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 677, in _load_unlocked
  File "/Users/mohamedmartino/opt/anaconda3/lib/python3.7/site-packages/PyInstaller/loader/pyimod03_importers.py", line 623, in exec_module
    exec(bytecode, module.__dict__)
  File "site-packages/dash_core_components/__init__.py", line 12, in <module>
FileNotFoundError: [Errno 2] No such file or directory: '/var/folders/np/m30g9mj57h72n68qxc2tq61m0000gn/T/_MEI2yKNs4/dash_core_components/package-info.json'
[85571] Failed to execute script app
  • I'm new to coding, and I can't figure out why it can't find the dcc
    dependency. Is there a better way to compile my modules into one
    executable file?

I have a few python modules and excel files as well as an -asset folder with images and css files.

like image 655
Martino Avatar asked Dec 18 '22 14:12

Martino


2 Answers

It seems that we need to modify .spec file(see sample.spec in below).
After modified the spec file, input 'pyinstaller ***.spec' in the console (It seems '--onefile' option does not work), then you can connect your dash URL from a browser.

#Sample.spec
# -*- mode: python ; coding: utf-8 -*-

#manually add Start to avoid rerusion limit error==>
import sys
sys.setrecursionlimit(5000)
#manually add End<==

block_cipher = None


a = Analysis(['dashtest.py'],
             pathex=['C:\\Users\\Owner\\Documents\\python\\Simulatortest\\sandbox'],
             binaries=[],
             #modified Start==>
             datas=[
                 ('C:\\Users\\Owner\\anaconda3\\pkgs\\dash-core-components-1.3.1-py_0\\site-packages\\dash_core_components\\', 'dash_core_components'),
                 ('C:\\Users\\Owner\\anaconda3\\pkgs\\dash-html-components-1.0.1-py_0\\site-packages\\dash_html_components\\', 'dash_html_components'),
                 ('C:\\Users\\Owner\\anaconda3\\pkgs\\dash-renderer-1.1.2-py_0\\site-packages\\dash_renderer\\','dash_renderer'),
                 ],
             hiddenimports=['pkg_resources.py2_warn'],
             #modified End<==
             hookspath=[],
             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,
          [],
          exclude_binaries=True,
          name='dashtest',
          debug=False,
          bootloader_ignore_signals=False,
          strip=False,
          upx=True,
          console=True )
coll = COLLECT(exe,
               a.binaries,
               a.zipfiles,
               a.datas,
               strip=False,
               upx=True,
               upx_exclude=[],
               name='dashtest')
like image 100
koukoui Avatar answered Dec 31 '22 20:12

koukoui


If Pyinstaller is having trouble finding a file (like a Python module), then you can add the address to that file as a Tuple in the datas array of the .spec file. As the Pyinstaller documentation says,

  • The first string specifies the file or files as they are in this system now.
  • The second specifies the name of the folder to contain the files at run-time.

In the docs they have the following example:

a = Analysis(...
     datas= [ ('/mygame/sfx/*.mp3', 'sfx' ) ],
     ...
     )

This results in the following:

All the .mp3 files in the folder /mygame/sfx will be copied into a folder named sfx in the bundled app.

If for example Pyinstaller can't find the Plotly Python module, then you would find where the Plotly module is installed in your computer, or virtual environment, and copy its location into the data array like so (in my case I have a virtual environment called "virtual_env_name"):

             datas=[
                    ('C:\\Users\\Nicolas\\.virtualenvs\\virtual_env_name\\Lib\\site-packages\\dash_core_components', 'dash_core_components'),
                    ('C:\\Users\\Nicolas\\.virtualenvs\\virtual_env_namea\\Lib\\site-packages\\dash_html_components\\', 'dash_html_components'),
                    ('C:\\Users\\Nicolas\\.virtualenvs\\virtual_env_name\\Lib\\site-packages\\dash_renderer\\', 'dash_renderer'),
                    ('C:\\Users\\Nicolas\\.virtualenvs\\virtual_env_name\\Lib\\site-packages\\plotly', 'plotly'),
                    ],

By doing this, Pyinstaller knows where all these modules are, and I can create my executable with the following line (if I weren't using a virtual environment):

pyinstaller python_script_name.spec

or if you have a virtual environment like I do, first activate the virtual environment:

pipenv shell

then run:

pyinstaller python_script_name.spec

If you keep getting a "FileNotFoundError" for a different file/module, then add the location of the missing file (or Python module) to the datas array.

Alternatively, it is possible that your antivirus is "quarantining" an installation file while Pyinstaller is creating your executable. So, if the datas array solution doesn't work, then maybe try temporarily disabling your antivirus, or its file scanning ability, during the creation of the executable (.exe file).

like image 21
Nicolas Mora Avatar answered Dec 31 '22 21:12

Nicolas Mora