I'm trying to convert my .py file into a .exe.
The app works until it is in exe form, and I get the following errors, generated from
http requests coming from the textmagic library:
File "main.py", line 88, in <module>
File "main.py", line 20, in send_generics
File "textmagic/rest/models/messages.py", line 91, in create
File "textmagic/rest/models/base.py", line 214, in create_instance
File "textmagic/rest/models/base.py", line 156, in request
File "textmagic/rest/models/base.py", line 121, in make_tm_request
File "textmagic/rest/models/base.py", line 86, in make_request
File "httplib2/__init__.py", line 1558, in request
File "httplib2/__init__.py", line 1077, in __init__
File "httplib2/__init__.py", line 172, in _build_ssl_context
FileNotFoundError: [Errno 2] No such file or directory
I've scavenged an identical issue with shotgun API on this forum and tweaked around patrick-hubert-adsk's response. This didn't work, but I may be doing something wrong here, particularly with the dst:
pyinstaller --add-data "`python3 -c
'import httplib2;
from httplib2 import certs;
import os;
cacerts = certs.where();
print("%s:textmagic%s" % (cacerts, os.path.dirname(cacerts[len(httplib2.__path__[0]):])))'`"
main.py
Any help is appreciated.
I would recommend specifying a few options on how to tell it to find & add -> bundling the files needed in your exe.
Before looking at the options below, basically you can tell it the path via command line while running it
On adding the files to your exe.; and bundling the files correctly into your exe.
This is important because it unpacks them during install, and using the os.path.join os.path.join etc.. as show in the samples below so it puts it in correct directory for the corresponding OS.
1 Adding/Locating files:
To ensure the files and their paths are found correctly, please list arguments in command prompt to be used/found by pyinstaller; --add-data "yourPath_to_file:yourPath_in_executable in directory"
// fore .g. here favicon.png is located in directory of socketserver.py
// which is later copied to the root directory of the executable (the `.` signifies root directory)
pyinstaller --add-data "favicon.png;." --onefile yourPythonProgam.py
2 Bundling files into your executables
I am assuming you know how to edit the spec file, if not here is a ref.
Also if its a --onedir distribution, just pass a list of files (in TOC format) to the COLLECT, and they will show up in the distribution directory tree. The name in the (name, path, 'DATA') tuple can be a relative path name. Then, at runtime, you can use code like this to find the file:
os.path.join(os.path.dirname(sys.executable), relativename))
And in a --onefile distribution, your/data files are bundled in the executable, and when its run its then extracted at runtime into the work directory, that directory is best found by os.environ['_MEIPASS2']. So, you can access those bundled files through ref: MEIPASS:
os.path.join(os.environ["_MEIPASS2"], relativename))
from os import path
bundle_dir = path.abspath(path.dirname(__file__))
path_to_dat = path.join(bundle_dir, 'other-file.dat')
What is MEIPASS/2
Ref for your [Spec file][4]
Runtime to find your bundled exe file
A
Adding files info:
Related
My Requirement
I have generated an exe from python code using pyinstaller. Since I am using pytesseract.image_to_pdf_or_hocr OCR operation Tesseract is the dependency. So I have added tesseract folders in spec file and generated the exe. My aim is to bundle tesseract folders inside the exe itself, so that tesseract folders will be copied in Temp files when I open the exe.
What have I done so far
I have successfully generated the exe from python code. When I open the exe the bundled tesseract files will be extracted to temp files directory and I can start using the tesseract.
Issue
Generally when we run pytesseract.image_to_pdf_or_hocr it will create a pdf (i am passing extension='pdf' parameter) in temp folder with some random name tess_rwsvvy4k.pdf. This works when I run code directly. But when I am running exe, it is not generating the pdf file in temp folder.
Error from Log file
File "PDF to Readable.py", line 216, in start_conversion
File "pytesseract\pytesseract.py", line 446, in image_to_pdf_or_hocr
File "pytesseract\pytesseract.py", line 290, in run_and_get_output
FileNotFoundError: [Errno 2] No such file or directory: 'C:\\Users\\PAVANS~1\\AppData\\Local\\Temp\\tess_rwsvvy4k.pdf'
Spec file
....
a = Analysis(
['PDF to Readable.py'],
pathex=[],
datas=[],
binaries=[('Source/poppler-0.68.0/bin/*', 'poppler-0.68.0/bin'),
('Source/poppler-0.68.0/include/poppler/cpp/*', 'poppler-0.68.0/include/poppler/cpp'),
('Source/poppler-0.68.0/lib/pkgconfig/*', 'poppler-0.68.0/lib/pkgconfig'),
('Source/poppler-0.68.0/lib/*.*', 'poppler-0.68.0/lib'),
('Source/poppler-0.68.0/share/man/man1/*', 'poppler-0.68.0/share/man/man1'),
('Source/TESSEERACT-OCR/*.*', 'TESSEERACT-OCR'),
('Source/TESSEERACT-OCR/doc/*', 'TESSEERACT-OCR/doc'),
('Source/TESSEERACT-OCR/tessdata/*.*', 'TESSEERACT-OCR/tessdata'),
('Source/TESSEERACT-OCR/tessdata/configs/*.*', 'TESSEERACT-OCR/tessdata/configs'),
('Source/TESSEERACT-OCR/tessdata/tessconfigs/*.*', 'TESSEERACT-OCR/tessdata/tessconfigs')],
.....
Guide me in the right direction...
Actually, I made a small mistake in spec file. Original tessdata\configs folder contains 25 files and tessdata\tessconfigs folder contains 6 files. But due to my mistake I got only 5 files in tessdata\configs folder. So I missed dependencies for hocr. So in my case I could not able to generate pdf.
My Mistake
('Source/TESSEERACT-OCR/tessdata/configs/*.*', 'TESSEERACT-OCR/tessdata/configs'),
('Source/TESSEERACT-OCR/tessdata/tessconfigs/*.*', 'TESSEERACT-OCR/tessdata/tessconfigs')
What I have changed
('Source/TESSEERACT-OCR/tessdata/configs/*', 'TESSEERACT-OCR/tessdata/configs'),
('Source/TESSEERACT-OCR/tessdata/tessconfigs/*', 'TESSEERACT-OCR/tessdata/tessconfigs')
So this will add all the files from the tessdata\configs and tessdata\tessconfigs folders. And I have got my desired output.
I get an error when i'm compiling with pyinstaller it works on my pc not on a different pc.
error i get
Traceback (most recent call last):
File "app.py", line 30, in <module>
password = parser.get('settings', 'password')
File "configparser.py", line 781, in get
File "configparser.py", line 1152, in _unify_values
configparser.NoSectionError: No section: 'settings'
[9464] Failed to execute script 'app' due to unhandled exception!
Here is my code
parser = ConfigParser()
parser.read('C:\\Users\\abc\Desktop\\Maker\\settings.ini')
I followed some solutions but still no luck is solving this can anyone please help?
I tried this solution as well with no luck
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.path.abspath(".")
return os.path.join(base_path, relative_path)
parser = ConfigParser()
settings_file = resource_path('settings.ini')
You have to make sure you are bundling your ini file with your application. This is a little more difficult if you are using UPX to compress all files into one executable file. I never saw the point in this because it seems like a false savings. Every time you run the EXE it will decompress all files into a temporary folder. Then your application now consumes all of the uncompressed space plus all of the compressed space. Bleah.
I would recommend you use a Spec file to specify all of the additional
files you want to include with your application.
For debugging purposes, you can put this in your program to make sure the ini file is where you think it is (you can delete it or comment it out once you verify the file is there)
print(os.listdir(<path>))
or
print(os.listdir(os.getcwd()))
where getcwd stands for 'get current working directory' which should be the directory where your EXE resides.
If you don't want to mess with a spec file, you can pass the --add-data parameter to pyinstaller and pass your ini file.
I have a python file I am converting to exe via Pyinstaller. The coversion runs fine with no error, however when I run the exe file I get error in line 13 of the python file (line is import librosa). Then I get a bunch of files and then a
FileNotFoundError: No file or directory: 'C:\\Users\\johnny\\Appdata\\Local\\Temp\\_MEI70722\\librosa\\util\\example_data\\registry.txt'.
Also the python file itself runs fine.
Any help would be appreciated
PyInstaller tries to find all the dependencies, however this file is not imported but loaded so it misses it. You can simply force it to add it:
--add-data [path to your python]/Lib/site-packages/librosa/util/example_data;librosa/util/example_data
With The full command be like :
pyinstaller --onefile [YourScript].py --add-data [path to your python]/Lib/site-packages/librosa/util/example_data/registry.txt;librosa/util/example_data
You'll need to specify the data files as PyInstaller hooks.
Create a folder "extra-hooks", and in it a file "hook-librosa.py"
paste these 2 lines in "extra-hooks/hook-librosa.py":
from PyInstaller.utils.hooks import collect_data_files
datas = collect_data_files('librosa')
Then tell PyInstaller where to locate this file with adding 1 of the following to your PyInstaller command:
--additional-hooks=extra-hooks
--additional-hooks-dir "[PATH_TO_YOUR_PROJECT]/axtra-hooks"
The 2nd one worked for me, and I was using auto-py-to-exe, built on PyInstaller.
I guess the file doesn't exist. Open a file manager and copy the directory.
In the PyInstaller, you should type in the python file's name and then --onefile. It makes an .EXE file (if you are on windows) with all the imported files within. You can learn more here: https://pyinstaller.readthedocs.io/en/stable/usage.html
I've been working on getting a python executable working for OSX El Capitan, and i successfully get the executable built using both Pyinstaller and cx_Freeze, the issue comes when i actually run the executable on another mac. The error i get is about not being able to find the .db file referenced in my main script, so i looked at documentation for both programs and came across sys.MEIPASS (Pyinstaller) and sys.executable (cx_Freeze) to include data files in the --onefile app. This is the code i used in my main script:
def find_data_file(filename):
if getattr(sys, 'frozen', False):
# The application is frozen
datadir = os.path.dirname(sys._MEIPASS) #in cx_Freeze this is sys.executable
else:
# The application is not frozen
# Change this bit to match where you store your data files:
datadir = ospath.abspath(os.pardir)
return os.path.join(datadir, filename)
#This is how im using the "find_data_file" function in my code.
dbpath = find_data_file('PubData.db')
conn = lite.connect(dbpath)
ive changed it a bit in the else statement to match the layout of my project directories, and it works perfectly fine when running an unfrozen application.
However when i try to run using the built executable it gives me an error about not being able to find the .db file, which i thought referencing sys.MEIPASS or sys.executable would fix.
Error:
Traceback (most recent call last):
File "interface/GUI.py", line 673, in <module>
File "interface/GUI.py", line 82, in __init__
File "interface/GUI.py", line 212, in getServerNames
sqlite3.OperationalError: no such table: servernames
This is how my file tree looks:
PubData-master ##(Project Root Directory)
Interface ##(Directory)
GUI.py ##(Main Script, this is where i reference 'PubData.db')
GUI.spec ##(Pyinstaller spec file)
PubData.db ## This is my database file, in the PubData-master Directory
If anyone could tell me what i am doing wrong, or give me a solution, i would be extremely grateful!
if you are trying to access any data file you specified in the .spec file, in your code, you must use Pyinstaller's _MEIPASS folder to reference your file. Here is how i did so with the file named Data.db:
import sys
import os.path
if hasattr(sys, "_MEIPASS"):
datadir = os.path.join(sys._MEIPASS, 'Data.db')
else:
datadir = 'Data.db'
conn = lite.connect(datadir)
this replaced the following single line:
conn = lite.connect("Data.db")
This link explained it very well:
https://irwinkwan.com/2013/04/29/python-executables-pyinstaller-and-a-48-hour-game-design-compo/
Both files, the .py file and a .txt file it calls with
champions_list = open('champions.txt','rU').read().split('\n')
are in the file folder C:\Users\[My Name]\Programming\[file name].
I'm calling the .py file through Command prompt and it returns the error
IOError: [Errno 2] No such file or directory: champions.txt
Has this happened to anyone else before?
When you open a file with open('champions.txt'), then the OS expects to find the champions.txt file in the current directory. The current directory is the directory of the command prompt window where you started the program. This is not (necessarily) the same as the directory where the Python script is stored.
You may be able to fix this by doing:
import os
import sys
open(os.path.join(os.path.dirname(sys.argv[0]), 'champions.txt')
This takes the full name of the script in sys.argv[0], takes the directory part, and then joins that to the file name you want. This will open the file in the script directory, not the current directory.
(Note that using sys.argv[0] in this way is OS-dependent, and works on Windows but may not work the same way on other systems.)
Just because the file is in the same folder as the script does not mean the python interpreter knows that the file is there. It is looking for a file in the cwd. You can:
Try using the full absolute path of the file; or
Add the directory containing the file using os.path.append