Reputation: 89
I have a working Python 3 script, inventoryScraper.py, that I am trying to make into a 1 file executable I can distribute. I have been using Pyinstaller 3 with Python 3, it has worked in the past. I have a file 'Store_Codes.csv' that my script needs to run, and I want it included inside the executable.
I have read and attempted all the previous answers relating to this, and it has not worked/I messed it up. The resulting .exe works when the Store_Codes.csv is in the same folder as the exe, but not otherwise. I am definitely a novice to Python, but the person I'm giving this to has no experience whatsoever with command lines or anything related, so it's important it be an all-in-one file.
I have modified the spec file in every way I have seen on other posts, and none have worked, I am sure I am misunderstanding, and I could really use the help.
What is the straightforward way, with Pyinstaller 3, to include data files in a onefile exe?
Thank you!
Upvotes: 4
Views: 4145
Reputation: 473
Store_Codes.csv
in the same folder as the .py file. data
in the .spec file you add datas=[( 'Store_Codes.csv', '.' )],
You should add to your .py file
if getattr(sys, 'frozen', False):
# if you are running in a |PyInstaller| bundle
extDataDir = sys._MEIPASS
extDataDir = os.path.join(extDataDir, 'Store_Codes.csv')
#you should use extDataDir as the path to your file Store_Codes.csv file
else:
# we are running in a normal Python environment
extDataDir = os.getcwd()
extDataDir = os.path.join(extDataDir, 'Store_Codes.csv')
#you should use extDataDir as the path to your file Store_Codes.csv file
compile the file.
When you start the .exe
it creates a temporary folder in the appropriate temp-folder location for the OS. The folder is named _MEIxxxxxx
, where xxxxxx is a random number. All the files you need to run the script will be there
The sys._MEIPASS
is the path for this temporary folder.
When you add datas=[( 'Store_Codes.csv', '.' )]
to your spec file. It will copy the file to the main folder of the bundle. If you want to keep it organized you can create a different folder using datas=[( 'Store_Codes.csv', 'another_folder' )]
, then in your code you would have
if getattr(sys, 'frozen', False):
# if you are running in a |PyInstaller| bundle
extDataDir = sys._MEIPASS
extDataDir = os.path.join(extDataDir,another_folder, 'Store_Codes.csv')
#you should use extDataDir as the path to your file Store_Codes.csv file
else:
# we are running in a normal Python environment
extDataDir = os.getcwd()
extDataDir = os.path.join(extDataDir,another_folder 'Store_Codes.csv')
#you should use extDataDir as the path to your file Store_Codes.csv file
Upvotes: 6
Reputation: 2391
Well there's actually an easiest work around, rename your Store_Codes.csv
into Store_Codes.py
then edit the file:
csv_codes = """
csv file content...
"""
In your main script: import Store_Codes
and then csv_file_content = Store_Codes.csv_codes
.
Then in pyinstaller
use --onefile
, it'll automatically include Store_Codes.py
into your newly generated exe file.
P.S. If it's utf-8
encoded content in the csv file, don't forget # -*- coding: utf-8 -*-
Upvotes: 0