I'm trying to learn PyInstaller. I created two simple files, Test.py:
import os
and Test.spec:
anal = Analysis (["Test.py"])
pyz = PYZ(anal.pure)
exe = EXE(anal.scripts, pyz, name="Test.exe", exclude_binaries=1, debug=1)
coll = COLLECT(exe, anal.binaries, name="dist")
Then I ran:
Build.py Test.spec
This ran without any error mesages, and produced a directory dist with several files, including Test.exe. When I ran Test.exe, it failed with the output:
Found embedded PKG: C:\Documents and Settings\Rade\My Documents\Development\Test\Test.exe
Extracting binaries
manifestpath: C:\Documents and Settings\Rade\My Documents\Development\Test\Test.
exe.manifest
Error activating the context
python27.dll
Manipulating evironment
PYTHONPATH=C:/Documents and Settings/Rade/My Documents/Development/Test
importing modules from CArchive
extracted iu
extracted struct
extracted archive
Installing import hooks
outPYZ1.pyz
Running scripts
Traceback (most recent call last):
File "<string>", line 1, in <module>
ImportError: No module named os
RC: -1 from Test
OK.
I'm sure I have made some stupid beginner's mistake, but what?
For simple files like this, you should use Makespec.py for creating spec's instead of writing manually. For large projects, you could use the Makespec.py's output as a template and edit them.
http://www.pyinstaller.org/export/latest/tags/1.4/doc/Manual.html#create-a-spec-file-for-your-project
Related
I am trying to build a python script via PyInstaller. I have used the following commands to configure, generate a spec file, and build:
wget pyinstaller.zip, extracted it, python Configure.py, etc, then:
python pyinstaller/Makespec.py --onefile myscript.py
python pyinstaller/Build.py myscript.spec
Here is the spec file it generated:
# -*- mode: python -*-
a = Analysis([os.path.join(HOMEPATH,'support/_mountzlib.py'), os.path.join(HOMEPATH,'support/useUnicode.py'), 'icinga.py'],
pathex=['/home/user/projects/icinga_python/releases/v2.1'])
pyz = PYZ(a.pure)
exe = EXE( pyz,
a.scripts,
a.binaries,
a.zipfiles,
a.datas,
name=os.path.join('dist', 'myscript'),
debug=False,
strip=False,
upx=True,
console=1 )
This built an executable file in dist/ directory. When trying to run this file, I get the following:
Traceback (most recent call last):
File "<string>", line 12, in <module>
File "/home/user/projects/myscript/releases/v2.1/pyinstaller/iu.py", line 455, in importHook
raise ImportError, "No module named %s" % fqname
ImportError: No module named mysql
If I moved this executable into the directory of the actual Python code, it gave different results:
Traceback (most recent call last):
File "<string>", line 12, in <module>
File "/home/user/projects/myscript/releases/v2.1/pyinstaller/iu.py", line 436, in importHook
mod = _self_doimport(nm, ctx, fqname)
File "/home/user/projects/myscript/releases/v2.1/pyinstaller/iu.py", line 521, in doimport
exec co in mod.__dict__
File "CLUSTER/mysql/icingasql.py", line 13, in <module>
import urllib2
File "/home/user/projects/myscript/releases/v2.1/pyinstaller/iu.py", line 455, in importHook
raise ImportError, "No module named %s" % fqname
ImportError: No module named urllib2
In the ... pyinstaller docs I see that --onefile is the option I need/want, but for some reason not everything is being compiled in.
The script is not really including anything fancy, just little quick modules I wrote for sql statements, and parsing certain websites.
The problem is that pyinstaller won't see second level imports. So if you import module A, pyinstaller sees this. But any additional module that is imported in A will not be seen.
There is no need to change anything in your python scripts. You can directly add the missing imports to the spec file.
Just add the following in a = Analysis(...):
hiddenimports=["mysql"],
This should be the result:
a = Analysis([os.path.join(HOMEPATH,'support/_mountzlib.py'), os.path.join(HOMEPATH,'support/useUnicode.py'), 'icinga.py'],
pathex=['/home/user/projects/icinga_python/releases/v2.1'], hiddenimports=["mysql"],)
After that run pyinstaller with the spec file as an argument.
This error can ocurre when you have dynamic imports in your code. In that case, pyinstaller don't include those packages in exe file. In that case you can:
Add unused import of those packages in your code
Tell pyinstaller to include it
One file option does not change anything in running your code. If you create --onefile exe all files created by pyinstaller are packed to exe file, and unpacked to local temp every time you run exe.
just gonna add my 2 cents because I encountered the same problem today - 6 years later :D
For Windows:
1) cmd => rightclick => with admin rights
2) Enter in cmd: "pip install pyinstaller"
3) navigate in cmd to the folder of "yourMain.py"
4) Enter in cmd: "pyinstaller --onefile --windowed yourMain.py"
5) If you import other scripts / data in "yourMain.py":
Manually enter the folder "dist" (gets created - where "yourMain.exe" should be by now),
and copy your scripts or folder structure there
(e.g. /assets/sounds; /assets/graphics; /scripts; anotherscript.py )
Then I was able to run the exe by double clicking.
Turned out to be pretty easy. What did the trick for me was the "--onefile" and adding my other files to the "dist" folder.
The "--windowed" is just so the python command window won't pop up when you start the exe.
I am trying to generate a notification in windows using plyer library in python. It works fine when the python script is run. But when I try to create an executable file using pyinstaller and run the executable I keep getting this error
Traceback (most recent call last):
File "site-packages\plyer\utils.py", line 96, in _ensure_obj
ModuleNotFoundError: No module named 'plyer.platforms'
Traceback (most recent call last):
File "in_time.py", line 131, in <module>
File "site-packages\plyer\facades\notification.py", line 84, in notify
File "site-packages\plyer\facades\notification.py", line 90, in _notify
NotImplementedError: No usable implementation found!
This is the snippet of the code
from plyer import notification
notification.notify(
title='9 hours Completed',
message='You have successfully completed 9hrs for the day',
app_name='In Time App',
app_icon='Time3.ico'
)
When creating the executable with pyinstaller, add this to the command:
--hidden-import plyer.platforms.win.notification
I am using Windows and the solution with hiddenimports didn't work for me.
There's an other solution by copying the plyer package from python site_packages to the application directory as described here:
https://stackoverflow.com/a/64448486/11362192
The copying of this package can also be automated. To do this, add the original path to the plyer package as datas to the spec file:
site_packages_dir = 'C:/Python/Python310/Lib/site-packages/'
a = Analysis(
...
datas=[(site_packages_dir+'plyer', './plyer')],
...
add following hidden import to spec file
a = Analysis(
...
hiddenimports=['plyer.platforms.win.notification'],
...
pyinstaller --onefile --hidden-import plyer.platforms.linux.notification filename.py
if you are using linux
plyer.platforms.win.notification
if you are using win
There are also ios, macos, android platforms available so if you are using that, you may want to use those. If it doesn't work then you may want to check the plyer.platforms.<your_flatform> directory and see if notifications.py is existing or not.
I am trying to run a python pipeline through Mac OS Terminal. I am using Python 2.7.15 because newer versions of Python gave me error messages with this file. I keep getting the following error message:
$ python ../../../scripts/gemmaPipeline.py ../../../data/all.fixGL.Q10.ap.bi.MAF5.vcf.gz outfile Results
Traceback (most recent call last): File
"../../../scripts/gemmaPipeline.py", line 5, in
import utils, vcf, genomes100, gemma ImportError: No module named genomes100
The modules listed in the import command are present under the "scripts" folder in a subfolder "modules". For each of the four modules, I have a .py and .pyc file in this subfolder. I cannot get Python to find this path.
I have tried running the same script within a virtualenv but to no avail. I even tried moving the "modules" subfolder to the Python "site-packages" folder in hopes that it would work but failed.
Finally, I tried including an init.py file (blank) in the "script" folder, but that didn't work either.
I am an utter novice and am pretty much learning as I go.Please help.
I'm trying to use sphinx to generate documentation for a package that I wrote. Everything was working great until I added some code that used another package I wrote that wraps some boost-python modules.
Now when I run make html I get this (edited for clarity):
$ make html
sphinx-build -b html -d build/doctrees source build/html
Running Sphinx v1.3.1
loading pickled environment... done
building [mo]: targets for 0 po files that are out of date
building [html]: targets for 0 source files that are out of date
updating environment: 0 added, 1 changed, 0 removed
reading sources... [100%] my_project
/path/to/my_project/my_project/docs/source/my_project.rst:19: WARNING: autodoc: failed to import module u'my_project.my_module'; the following exception was raised:
Traceback (most recent call last):
File "/Users/harding/anaconda/lib/python2.7/site-packages/Sphinx-1.3.1-py2.7.egg/sphinx/ext/autodoc.py", line 385, in import_object
__import__(self.modname)
File "/path/to/my_project/__init__.py", line 12, in <module>
from . import module_that_uses_boost_python_classes
File "/path/to/module_that_uses_boost_python_classes.py", line 10, in <module>
import package_that_wraps_boost_python_classes
File "/path/to/package_that_wraps_boost_python_classes/__init__.py", line 21, in <module>
from native_boost_python_module import *
ImportError: dlopen(/path/to/native_boost_python_module.so, 2): Library not loaded: cpp_library.dylib
Referenced from: /path/to/native_boost_python_module.so
Reason: image not found
The problem is that when sphinx trys to import my module, it fails to load the linked c++ library from my boost-python related package. That package is installed via pip and it loads fine in all other situations.
I manually specified the full path to all the c++ libraries with install_name_tool -change and then sphinx works fine.
My question is this: how can I get sphinx to import my boost-python package without manually editing the c++ libraries manually with install_name_tool?
I have DYLD_LIBRARY_PATH set to include the directory that contains all the c++ libraries.
I'm on MacOS Sierra
I am trying to use py2exe to distribute a python application I have written. Everything seems to go OK, but when I run it on another machine it fails with the following error:
Traceback (most recent call last):
File "application.py", line 12, in <module>
File "win32api.pyc", line 12, in <module>
File "win32api.pyc", line 10, in __load
ImportError: DLL load failed: The specified procedure could not be found.
I have googled for this and not found very much, but have tried the following suggestions to no avail:
Imported pywintypes and pythoncom before win32api (in the setup.py for py2exe and in the main application)
Added some code to the setup.py -
# ModuleFinder can't handle runtime changes to __path__, but win32com uses them
import pywintypes
import pythoncom
import win32api
try:
# if this doesn't work, try import modulefinder
import py2exe.mf as modulefinder
import win32com
for p in win32com.__path__[1:]:
modulefinder.AddPackagePath("win32com", p)
for extra in ["win32com.shell"]: #,"win32com.mapi"
__import__(extra)
m = sys.modules[extra]
for p in m.__path__[1:]:
modulefinder.AddPackagePath(extra, p)
except ImportError:
# no build path setup, no worries.
pass
I'm quite new to all this, so any help would be greatly appreciated
Thanks
Jon
I've seen this problem when the package was built on Vista but executed on XP. The problem turned out to be that py2exe mistakenly added powrprof.dll and mswsock.dll to the package. Windows XP contains its own copies of these files though, and can't load the Vista ones which got installed with your app.
Removing them from the package did the trick, you can do this easy by adding this to the options dict in setup.py
'dll_excludes': [ "mswsock.dll", "powrprof.dll" ]
#Wim, I found the bit about "adding this to the options dict in setup.py" a bit confusing. If like me you did not have an options arg in your existing call to setup this might make things clearer:
setup(name='myprog',
...
options={"py2exe":{"dll_excludes":[ "mswsock.dll", "powrprof.dll" ]}},
...
)
Try adding win32api to your packages, in the options dictionary.
Here's an example:
excludes = ["pywin", "pywin.debugger"] # there will be more in real life...
options = dict(optimize=2,
dist_dir="build",
excludes=excludes,
packages=["win32api"])
setup(
name="MyCoolApp",
options=dict(py2exe=options),
# etc ...
Just as an added comment. When rebuilding your program with Py2exe be sure to delete the old "dist" directory. I was sitting for over 3 hours not understanding why my app was working on my dev envirnoment and not in production. deleted dist and rebuild with py2exe and it worked.