I have a GUI script, called ui.py, created in PySide that uses functions from another script, called DataFunctions.py. When I run the ui.py file in python it all works perfectly, and when I run the ui.exe file it will all work fine apart from the button that runs the DataFunctions.py file, which does nothing.
In my ui.py file I am importing DataFunctions.py with:
import DataFunctions.py
buttonAction = DataFunctions.writeFile(filename, data)
I am using the following code to create the .exe:
pyinstaller ui.py -w -F
Am I importing the DataFunctions.py file in a way that pyinstaller doesn't support?
Drop the .py extension in the import line
import Datafunctions
Make sure the Datafunctions.py code is in the same folder.
It turns out that the DataFunctions.py file was included in the .exe, however some file paths relative to the DataFunctions.py file inside it were not set correctly due to the .exe being created in another folder. If anyone else is having similar problems, make sure you don't specify -w so that you can use the console to debug your .exe. Look here for how to find the location of the .exe file when it is run.
Related
edit: How To Use --add-data with an entire folder?
Im converting my .py file to .exe using pyinstaller. but when i run it, it gives me this error:
Failed To Execute Script "test.py" due to unhandled exception: Couldn't open "C:\Users\Dani\AppData\Local\Temp_MEI11962\button_start.png" no such file or directory
Failed To Obtain/Convert Traceback!
Therefore My Converted Python File (exe) Was in the same directory As My Image.
My path code is built like this:
from locate import this_dir
path = this_dir()
str(path) + "\\button_start.png"
A possible solution is to use pyinstaller's --add-data argument as shown in the documentation. You can either append this to your command when building the .exe or include that in a pyinstaller.spec file.
Additional information:
When you execute a .exe, that was created with pyinstaller, it will create a temporary folder that is named _MEI<some numbers>, just as you showed above. In there, it expects all the necessary files. Therefor, this is also the place, where it will search for the image, no matter where you put your .exe to or where you execute it. Since this folder is generated temporarily every time you start the .exe, it would not help to simply copy your image there.
I am creating a python script that should modify itself and be portable.
I can achieve each one of those goals separately, but not together.
I use cx_freeze or pyinstaller to pack my .py to exe, so it's portable; but then I have a lot of .pyc compiled files and I can't edit my .py file from the software itself.
Is there a way to keep a script portable and lightweight (so a 70mb portable python environment is not an option) but still editable?
The idea is to have a sort of exe "interpreter" like python.exe but with all the libraries linked, as pyinstaller allows, that runs the .py file, so the .py script can edit itself or be edited by other scripts and still be executed with the interpreter.
First define your main script (cannot be changed) main_script.py. In a subfolder (e.g. named data) create patch_script.py
main_script.py:
import sys
sys.path.append('./data')
import patch_script
inside the subfolder:
data\patch_script.py:
print('This is the original file')
In the root folder create a spec file e.g. by running pyinstaller main_script.py.
Inside the spec file, add the patch script as a data resource:
...
datas=[('./data/patch_script.py', 'data' ) ],
...
Run pyinstaller main_sript.spec. Execute the exe file, it should print
This is the original file
Edit the patch script to e.g. say:
print('This is the patched file')
Rerun the exe file, it should print
This is the patched file
Note: As this is a PoC, this works but is prone to security issues, as the python file inside the data directory can be used for injection of arbitrary code (which you don't have any control of). You might want to consider using proper packages and update scripts as used by PIP etc.
I have written code in python which opens up a template excel file. Everyday, a midnight, it copies that template into a new excel file where the code will record data into it for that day. My goal is to create a single executable file containing my code AND the template excel file using pyinstaller.
Basically I want to be able to open the template excel file regardless of whether the computer contains the file or not by bundling the excel file into the exe file obtained from pyinstaller:
Right now I open the excel file as shown below:
import os
import openpyxl
theFile = openpyxl.load_workbook(os.getcwd()+"\templateExcel.xlsx")
currentSheet = theFile[theFile.sheetnames[0]]
However, when I include the excel file to the pyinstaller command as --add-data "templateExcel.xlsx;templateExcel.xlsx, and run the exe file, it is not able to detect the location of the templateExcel file. I understand that by running on a different computer, the os.getcwd() gives a different path so it would obviously not be able to open the excel file. Hence I needed a way to bundle the excel file into the exe file such that the python code can find it regardless of the computer.
You can use;
Adding a data file in Pyinstaller using the onefile option
Summarly:
pyinstaller --onefile --nowindow --add-data text.txt;included winprint.py --distpath .
and sample python script:
import os
import sys
os.chdir(sys._MEIPASS)
os.system('included\\text.txt')
Please note:
When using "getcwd()" you won't receive the desired outcome you were looking for, it will get you the place from which you have executed your exe file.
For example, look at the following long module:
from os import getcwd
print(getcwd())
If you execute it from different locations, you will get different results:
Had PyInstaller worked like you assume it would (placing the file relative to some module) you could have used file instead of getcwd() as it indicated where the module resides (which is constant, unlike the location from which the exe is executed), but it doesn't.
Any way, #Sezer BOZKIR's answer should suffice, note the comment I added there.
I wrote a program in Python that includes external files, including images and a GUI .ui file.
I want to convert the Python script to a single executable (.exe) file using PyInstaller. When I try to open the .exe file, the program does not open.
You will need more information on why the application is closing immediately in order to solve your problem. To view the error messages associated with running your executable, run the .exe file from the command prompt: /path/to/app/dist/MyApp.exe. This will allow you to observe any errors that may exist after the app was bundled. If the program fails during an import statement, you may need to add a package to the hiddenimports list in the .spec file. Check the PyInstaller documentation for instructions on modifying the .spec file.
i have used pyinstaller to create a single .exe for windows using a single .py file and it worked fine. now i have gotten a bit more complex and have created multiple .py files stored in folders beneath my main.py. i've read through the pyinstaller guides , yet something doesn't seem to be working on my part..
my folder structure in windows is as follows, i'm just using a simple example for illustration :
app_root\main.py
app_root\__init__.py
\library\__init__.py
\library\app_ext1.py
\library\app_ext2.py
\library\test\__init__.py
\library\test\app3.py
in main.py i am importing code from
from library.app_ext1 import get_info
from library.app_ext2 import get_data
from library.test.app3 import get_test
so i run pyinstaller to my main.py using my .spec file.
in the .spec file i have
hiddenimports=['library']
pyinstaller finishes no errors and creates my single .exe, but when i run my single .exe i get the following error
C:\Users\user1\Desktop\1_file\dist>main.exe
Traceback (most recent call last):
File "app_root\main.py", line 2, in <module>
ImportError: No module named 'library'
Failed to execute script main
i wrote a test script just using a single .py file and it was doing some simple work with openpyxl (a python excel library) so in my test .py file i had "import openpyxl" , so in my spec file i used
hiddenimports=['openpyxl']
that worked fine but openpyxl is python lib that was installed using pip , i guess i'm not fully understanding how to import my own modules/scripts that i have created and stored in a folder structure beneath my main .py script file that i'm referencing between my .py script files as in my example above.
how can i make pyinstaller recognize my .py scripts i'm importing?
ok not sure why , but i just created a new folder in windows , copied all my .py files using same folder structure as before and then it worked. the only thing missing was all the Pycharm folders like .git, .idea, and pycache
i did notice in troubleshooting that if i renamed library to something else like "test" and updated my import lines it would still reference module "library" when i executed the .exe that was built.
i knew i was doing all this correctly but seems there might have been something in one of the other folders that py charm puts in there.
so i am just going to copy all my files to new folder each time and delete any folders/files i see other than the .py required.
In my case I replaced from library.app_ext1 import get_info to from your_newly_created_folder_name.library.app_ext1 and it worked :D
I noticed app_root name must be changed with new created folder name. just created a new folder, copy all .py files and keep folder structure. I hope you no one else will waste his time like me on this anymore