My solution is similar to @Stefano-Giraldi 's excellent solution. I was getting permission denied when passing directories to the shutil.copyfile.
I ended up using shutil.copytree:
import sys, os, shutil
site_packages = os.path.join(os.path.dirname(sys.executable), "Lib", "site-packages")
added_files = [
(os.path.join(site_packages, 'dash_html_components'), 'dash_html_components'),
(os.path.join(site_packages, 'dash_core_components'), 'dash_core_components'),
(os.path.join(site_packages, 'plotly'), 'plotly'),
(os.path.join(site_packages, 'scipy', '.libs', '*.dll'), '.')
]
working_dir_files = [
('assets', 'assets'),
('csv', 'csv')
]
print('ADDED FILES: (will show up in sys._MEIPASS)')
print(added_files)
print('Copying files to the dist folder')
print(os.getcwd())
for tup in working_dir_files:
print(tup)
to_path = os.path.join(DISTPATH, tup[1])
if os.path.exists(to_path):
if os.path.isdir(to_path):
shutil.rmtree(to_path)
else:
os.remove(to_path)
if os.path.isdir(tup[0]):
shutil.copytree(tup[0], to_path )
else:
shutil.copyfile(tup[0], to_path )
#### ... Rest of spec file
a = Analysis(['myapp.py'],
pathex=['.', os.path.join(site_packages, 'scipy', '.libs')],
binaries=[],
datas=added_files,
hiddenimports=[],
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,
a.binaries,
a.zipfiles,
a.datas,
[],
name='myapp',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
upx_exclude=[],
runtime_tmpdir=None,
console=True )
This avoids the _MEI folder and keeps it from copying config files that you want in your dist folder and not in a temp folder.
Hope that helps.