'pdflatex' not found in subprocess within a bundled PyInstaller APP - python

I am attempting to create a macOS standalone app from a PyQt5 GUI using PyInstaller. All works apart from automatically generating a PDF from a TEX file using the pdflatex module (in conjunction with Pylatex).
Both the pylatex and pdflatex modules require calling the subprocess module, which is done as following:
fp = subprocess.run(args, input=self.latex, env=env, timeout=15, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
Where args=['pdflatex', '-output-directory=/Users/Desktop', '-interaction-mode=batchmode', '-jobname=test']
This however does not work within the bundled app as it is crashing with the following error which I am logging to a file:
[Errno 2] No such file or directory: 'pdflatex'
Evidently, the pdflatex executable isn't being included/ found in the bundle. Running which pdflatex in the terminal outputs the following directory: /Library/TeX/texbin/pdflatex So I have tried to add the path with the following PyInstaller command:
pyinstaller --noconsole --onefile --path "/Library/TeX/texbin" main.py
But the app still cannot find the pdflatex executable at runtime, whereas the terminal executable works without issues. I have exhausted all similar posts online and ran out of things to try so I was hoping someone might guide me to the solution.
Related info:
macOS version: 10.13.6 High Sierra
Python: 3.8
PyInstaller: 5.1

I had the same problem and I just solved it by editing the runtime environment generated by PyInstaller. In my case the npm command was not found and after running which npm in terminal I could see that npm was located in /usr/local/bin, path that is not included by PyInstaller on macOS.
So my solution is to run this at app startup:
local_bin = '/usr/local/bin'
if local_bin not in os.environ["PATH"]:
os.environ["PATH"] += os.pathsep + local_bin

Related

The command in the exe file does not work

I have a python script running a command in the console. Everything works fine in the IDE, but after compiling it into an exe using pyinstaller (pyinstaller -F -i "C:\xampp\htdocs\organaizer\1.ico " websockets.py ) the command does not run. Error up VCRUNTIME140.dll' 14.12 is not compatible with this PHP build linked with 14.29 in Unknown on line 0. I notice that the window appears for a second and immediately disappears. I use Python 3.7. An example of a command that does not run in exe
import subprocess
import os
os.system('php artisan websockets:serve')
Tell me what the problem may be.
import subprocess
subprocess.call(['php', 'artisan', 'websockets:serve'])

(Pyinstaller) 'tclError: can't find package tkdnd' How can I fix this error?

I'm trying to package my project into an executable file using pyinstaller. main.py, my program, should run when I run the exe file. Exe because program has to run somehow without the user, who is not a developer in any way, needing to install modules and python itself. If there's a better/easier way please do tell me.
i installed tkinterdnd2 by using pip install tkinterdnd2.
Not sure if this is necessary, but here is the directory of the program: (the pngs are only used for my program, I don't think that is the culprit):
Folder
- cardiologist.png
- img.png
.
. # a couple more pngs
.
- main.py
- patients' data csv.csv
- patients' data xlsx test.xlsx
- sample.xlsx
- sun-valley.tcl #this file and the 'theme' folder below are for my program's theme, also don't think these are the culprit
- theme
- dark
- a lot of pngs...
- dark.tcl
- light
- a lot of pngs...
- light.tcl
Pyinstaller created 2 files, build and dist as expected.
build
- main
- base_library.zip
- certifi
- IPython
- jedi
- (some other files)
.
. a lot of .dylib files
.
- main # exe file to execute to run program
- matplotlib (this and next 4 are folders)
- numpy
- pandas
- parso
- PIL
- Python # exe file, don't know what this was created for
- (some more folders)
- tcl (this and next 2 are folders)
- tcl8
- 8.4
- platform
- .tm file
- .tm file
- 8.5
- 2 .tm files
- 8.6
- .tm file
- tdbc
- .tm file
- tkdnd2.8 (tried renaming to just tkdnd but same error)
- tk
- ttkwidgets
- 2 other folders
The command I used:
python -m PyInstaller main.py. # without python -m, 'command not found error' would happen
Error when running the produced exe:
Traceback (most recent call last):
File "tkinterdnd2/TkinterDnD.py", line 53, in _require
_tkinter.TclError: can't find package tkdnd
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "main.py", line 16, in <module>
File "tkinterdnd2/TkinterDnD.py", line 285, in __init__
File "tkinterdnd2/TkinterDnD.py", line 55, in _require
RuntimeError: Unable to load tkdnd library.
[7015] Failed to execute script 'main' due to unhandled exception!
logout
Saving session...
...copying shared history...
...saving history...truncating history files...
...completed.
I've went on the internet and tried looking for answers, but they either did not work for me, or wasn't clear enough like this: *.py script with tkinterdnd2 module doesn`t compile to an executable file (this solution still gave me the same error).
I've also tried using other modules to package such as cx_freeze and py2app, but both produced a different error, so I went back to pyinstaller for now. I'm on macOS.
Any way to fix this error?
EDIT
also tried python -m PyInstaller --clean -y -n "output_name" --add-data="tkdnd:tkdnd" main.py but same error produced when running.
There is a section on PyInstaller in tkinterdnd2 website.
Basically the required steps are:
copy hook-tkinterdnd2.py from the website to your project folder or create that file with below content:
from PyInstaller.utils.hooks import collect_data_files
datas = collect_data_files('tkinterdnd2')
run PyInstaller as below:
pyinstaller -F main.py --additional-hooks-dir=.
Or based on the command in your question:
python -m PyInstaller -F main.py --additional-hooks-dir=.
I finally made it work without manually moving folders.
pip install tkinterdnd2
I used auto py to exe and it didn't work with the "--add-binary" so I used "add-folder" in the gui, which is basically just "--add-data".
pyinstaller --noconfirm --onefile --windowed --add-data "<python_path>/Lib/site-packages/tkinterdnd2;tkinterdnd2/" "<your_script>"
The issue here is that Drag n Drop requires two components: the TCL libraries and the Tkinter interface to them. I install both manually to config my environment. (See my answer to How to Install and Use TkDnD with Python Tkinter on OSX?). I know someone packaged something on PyPI for the TkinterDnD2, but I haven't looked into it.
I have a project which uses TkinterDnD2. I build it with PyInstaller and see the same error you see (more or less). Running PyInstaller with the --onedir option (rather than the --onefile option), I saw that tkdnd2.8 was missing from my dist directory.
To rectify this, on Windows, I added
--add-binary "C:/Python/Python38-32/tcl/tkdnd2.8;tkdnd2.8"
to the PyInstaller command line, and that did the trick. I can now build a --onefile executable, and it runs without error.
You tried something similar, but I used the --add-binary rather than --add-data, and I give the full path to the libraries.
I'm not sure about the first hand experience of the other answers, but I personally distribute tkdnd in my applications. Granted, I first did this before tkinterdnd2 was available in PyPi. I used both the tkdnd distribution along with the python wrapper.
In my build script, I have
copy_tree('build_files/tkdnd2.9.2', os.path.dirname(sys.executable) + '/tcl/tkdnd2.9.2')
copy_tree('build_files/TkinterDnD2', os.path.dirname(sys.executable) + '/Lib/site-packages/TkinterDnD2')
And in my spec file,
tkdnd = [(os.path.abspath(file), 'tkdnd2.9.2') for file in iglob('build_files/tkdnd2.9.2/*.*')]
data_files = [...] + tkdnd
a = Analysis9(..., datas=data_files,...)
You can further take a look at the my project, Music Caster

After compiling a python script to EXE the Archive method doesn't work

I have a python script that I compiled to an EXE, one of the purposes of it is to extract a 7z file and save it to a destination.
If I'm running it from PyCharm everything works great, this is the code:
def delete_old_version_rename_new(self):
winutils.delete(self.old_version)
print("Extracting...")
Archive(f"{self.new_version}_0.7z").extractall(f"{self.destination}")
print("Finished")
os.rename(self.new_version, self.new_name)
I used pyinstaller to compile the program and used to command pyinstaller --onefile --paths {path to site packages} main.py
Thanks!
Single-file executables self-extract to a temporary folder and run from there, so any relative paths will be relative to that folder not the location of executable you originally ran.
My solution is a code snippet such as this:
if getattr(sys, 'frozen', False):
app_path = os.path.dirname(sys.executable)
else:
app_path = os.path.dirname(os.path.abspath(__file__))
which gives you the location of the executable in the single-file executable case or the location of the script in the case of running from source.
See the PyInstaller documentation here.
Eventually i just used a 7z command line i took from https://superuser.com/questions/95902/7-zip-and-unzipping-from-command-line
and used os.system() to initialize it.
Since my program is command line based it worked even better since its providing a status on the extraction process.
Only downside is i have to move the 7z.exe to the directory of my program.

cx_freeze executable - Py_Initialize: Unable to load the file system codec

I'm using cx_freeze to pack my Python script as a standalone executable.
The exe is running fine on the machine it was packed (with python 3.5 and all the relevant packages).
But when I copied the folder cx_freeze created to another machine the I got this error:
My cx_freeze script:
import sys
import numpy
import os.path
from cx_Freeze import setup, Executable
os.environ['TCL_LIBRARY'] = r'C:\Users\Administrator\AppData\Local\Programs\Python\Python36-32\tcl\tcl8.6'
os.environ['TK_LIBRARY'] = r'C:\Users\Administrator\AppData\Local\Programs\Python\Python36-32\tcl\tk8.6'
setup(
name = "DocSum",
version = "1.0",
options = {"build_exe": {"packages":["idna","asyncio", "encodings","numpy", "jinja2.ext"]}},
description = "DocSumRESTfulServer",
executables = [Executable("DocSumRESTfulServer.py", base = None)]
)
Any idea what could be the reason? I thought that the exe should be a standalone (run on machines without python). Am I wrong?
It seems that not all dependencies were compiled successfully.
If you want to have a standalone executable, I recommend pyinstaller.
Just pip install it then:
pyinstaller.exe --onefile yourFile.py
The --onefile flag is used to package everything into a single executable. Your executable file would be found on the dist folder.
You could also try this site.
I had the same problem. At the end I discovered that I need to copy also my python37.dll and the lib directory.
If the exe, dll and the directory are on the same directory, it works.
I would like to have a single exe too.

Any pyinstaller detailed example about hidden import for psutil?

I want to compile my python code to binary by using pyinstaller, but the hidden import block me. For example, the following code import psutil and print the CPU count:
# example.py
import psutil
print psutil.cpu_count()
And I compile the code:
$ pyinstaller -F example.py --hidden-import=psutil
When I run the output under dist:
ImportError: cannot import name _psutil_linux
Then I tried:
$ pyinstaller -F example.py --hidden-import=_psutil_linux
Still the same error. I have read the pyinstall manual, but I still don't know how to use the hidden import. Is there a detailed example for this? Or at least a example to compile and run my example.py?
ENVs:
OS: Ubuntu 14.04
Python: 2.7.6
pyinstaller: 2.1
Hi hope you're still looking for an answer. Here is how I solved it:
add a file called hook-psutil.py
from PyInstaller.hooks.hookutils import (collect_data_files, collect_submodules)
datas = [('./venv/lib/python2.7/site-packages/psutil/_psutil_linux.so', 'psutil'),
('./venv/lib/python2.7/site-packages/psutil/_psutil_posix.so', 'psutil')]
hiddenimports = collect_submodules('psutil')
And then call pyinstaller --additional-hooks-dir=(the dir contain the above script) script.py
pyinstall is hard to configure, the cx_freeze maybe better, both support windows (you can download the exe directly) and linux. Provide the example.py, In windows, suppose you have install python in the default path (C:\\Python27):
$ python c:\\Python27\\Scripts\\cxfreeze example.py -s --target-dir some_path
the cxfreeze is a python script, you should run it with python, then the build files are under some_path (with a lot of xxx.pyd and xxx.dll).
In Linux, just run:
$ cxfreeze example.py -s --target-dir some_path
and also output a lot of files(xxx.so) under some_path.
The defect of cx_freeze is it would not wrap all libraries to target dir, this means you have to test your build under different environments. If any library missing, just copy them to target dir. A exception case is, for example, if your build your python under Centos 6, but when running under Centos 7, the missing of libc.so.6 will throw, you should compile your python both under Centos 7 and Centos 6.
What worked for me is as follows:
Install python-psutil: sudo apt-get install python-psutil. If you
have a previous installation of the psutil module from other
method, for example through source or easy_install, remove it first.
Run pyinstaller as you do, without the hidden-import option.
still facing the error
Implementation:
1.python program with modules like platform , os , shutil and psutil
when i run the script directly using python its working fine.
2.if i build a binary using pyinstaller. The binary is build successfully. But if i run the binary iam getting the No module named psutil found.I had tried several methods like adding the hidden import and other things. None is working. I trying it almost 2 to 3 days.
Error:
ModuleNotFoundError: No module named 'psutil'
Command used for the creating binary
pyinstaller --hidden-import=['_psutil_linux'] --onefile --clean serverHW.py
i tried --additional-hooks-dir= also not working. When i run the binary im getting module not found error.

Categories

Resources