Search code examples
pythoncmdpyinstallereda

Pyinstaller packing of D-tale


I'm trying to use pyinstaller (latest version) to package D-table as an EXE file, but I'm getting this error:

FileNotFoundError: No such file of directory: ...\dash_colorscales\metadata.json.**
FileNotFoundError: No such file of directory: ...\dtale\translations.

I have tried to use a hook file as below, but still it didn't work.

from PyInstaller.utils.hooks import collect_data_files, collect_submodules
hiddenimports = collect_submodules('dtale')
datas = collect_data_files('dtale', include_py_files=True)

How can I fix this?

Here is my main.py file:

import dtale

if name == 'main':
    dtale.show().open_browser()
    app = dtale.app.build_app(reaper_on=False)
    app.run(host="0.0.0.0", port=8080)

Solution

  • You need to add all of the json and js files from the dash_daq and dash_colorscales as data with the compiled contents.

    These are the steps I took to compile and run the application.

    1. Open a new directory and cd into it.

    2. Create a clean virtual env with python -m venv venv and activate it with venv\scripts\activate

    3. Install dependencies with pip install dtale pyinstaller

    4. I copied the example code from the dtale GitHub page into a main.py file

      main.py

      import dtale
      import pandas as pd
      df = pd.DataFrame([dict(a=1,b=2,c=3)])
      d = dtale.show(df, subprocess=False)
      tmp = d.data.copy()
      tmp['d'] = 4
      d.kill()
      d.open_browser()
      dtale.instances()
      
    5. Run pyinstaller -F --collect-all dtale main.py

    6. Inside of the created .spec file, add the following lines at the top.

      # -*- mode: python ; coding: utf-8 -*-
      from PyInstaller.utils.hooks import collect_all
      import os
      
      dash_daq = "./venv/Lib/site-packages/dash_daq/"
      datas = [
          ('./venv/Lib/site-packages/dash_colorscales/metadata.json', './dash_colorscales/'),
          ('./venv/Lib/site-packages/dash_colorscales/bundle.js', './dash_colorscales/')]
      for filename in os.listdir(dash_daq):
          if os.path.splitext(filename)[1] in [".js", ".json"]:
              filepath = os.path.join(dash_daq, filename)
              datas.append((filepath, "./dash_daq/"))
      
      binaries = []
      hiddenimports = []
      tmp_ret = collect_all('dtale')
      datas += tmp_ret[0]; binaries += tmp_ret[1]; hiddenimports += tmp_ret[2]
      
      block_cipher = None
      
    7. Run pyinstaller main.spec

    8. Run dist/main.exe

    And Bob’s your uncle.