Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pyinstaller 3 adding datafiles with --onefile

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!

like image 635
Clive Avatar asked Sep 07 '25 16:09

Clive


1 Answers

  1. Put the Store_Codes.csv in the same folder as the .py file.
  2. On the field data in the .spec file you add datas=[( 'Store_Codes.csv', '.' )],
  3. 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
    
  4. compile the file.

Discussion

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
like image 182
Rafael Avatar answered Sep 10 '25 09:09

Rafael