I'm fairly new with programming (and with Python) and the Stack Overflow question/response system allowed me to resolve all my problems until now. I didn't find any post directly addressing my current issue, but have to admit that I don't really know what's wrong. Let me explain.
I'm trying to make an executable file of a *.py
script using PyInstaller. There's no problem doing it with a simple Python script (using --onefile), but it does not work when it comes to a more complex program that uses other *.py
and *.txt
files. I know that I need to modify the specification file and tried many alternatives - adding hidden files for instance.
Here are the files:
UpdatingStrategy.py
(the target file to transform in executable)LPRfunctions.py
(UpdatingStrategy.py
imports functions from this file)The following *.txt
files are read by UpdatingStrategy.py
:
Strategy_Observ.txt
Strategy_Problems.txt
Updating_Observ1.txt
Updating_Observ2.txt
Updating_Problems.txt
I'm using Python 3.5 and Windows 10. Tell me if you need extra information.
How do I use the specification file properly and modify it in order to make an executable file of UpdatingStrategy.py
?
I have read the PyInstaller documentation, but I lack many key principles and I couldn't make it work.
After the line
a = Analysis( ... )
add
a.datas += [
("/absolute/path/to/some.txt","txt_files/some.txt","DATA"),
("/absolute/path/to/some2.txt","txt_files/some2.txt","DATA"),
("/absolute/path/to/some3.txt","txt_files/some3.txt","DATA"),
]
Then in your program use the following to get the resource path of your .txt files.
def resource_path(relative_path):
""" Get absolute path to resource, works for dev and for PyInstaller """
try:
# PyInstaller creates a temp folder and stores path in _MEIPASS
base_path = sys._MEIPASS
except Exception:
base_path = os.environ.get("_MEIPASS2",os.path.abspath("."))
return os.path.join(base_path, relative_path)
...
txt_data = open(resource_path("txt_files/some.txt")).read()
Make sure you build it like python -m PyInstaller my_target.spec
... do not call PyInstaller directly against your .py file after you have edited your specification file or it will overwrite your edited file...
Anyone reading this in 2021... I've just run into similar issue with Pyinstaller. Needed to add a text file to my python code:
pyinstaller --add-data "/my/path/to/mytextfile.txt:/path/mytextfile.txt" mypython.py --onedir or --onefile
No matter if onedir or onefile, my code just never found the text file. Infact it threw the error:
IsADirectoryError: [Errno 21] Is a directory: /path/mytextfile.txt
Which didn't make sense to me because that's a file not a folder. Only when I checked this with the --onedir flag and I followed the path, I realized that pyinstaller would not only create a folder path, but also folder mytextfile.txt and put mytextfile.txt in there... so really the --add-data flag only wants a destination folder not the path to the file.
pyinstaller --add-data "/my/path/to/mytextfile.txt:path" mypython.py
or in the spec file i.e mypython.spec
datas=[('/my/path/to/mytextfile.txt', 'path')]
Should fix this. Note also the "DATA" configuration in the spec file is gone.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With