How can I use py2exe with arcpy? - python

I'm trying to convert a python script to a stand-alone executable using py2exe. The script is built mostly using arcpy, with a Tkinter GUI.
The setup.py script is as follows:
from distutils.core import setup
import py2exe
script = r"pathtoscript.py"
options = {'py2exe':{
"includes": ['arcpy', 'arcgisscripting'],
"packages": ['arcpy', 'arcgisscripting'],
"dll_excludes": ["mswsock.dll", "powrprof.dll"]
}}
setup(windows=[script], options=options)
When run, setup.py creates the .exe as expected, but when I try to run the executable, I get the following error:
Traceback (most recent call last):
File "autolim.py", line 7, in <module>
File "arcpy\__init__.pyc", line 21, in <module>
File "arcpy\geoprocessing\__init__.pyc", line 14, in <module>
File "arcpy\geoprocessing\_base.pyc", line 14, in <module>
File "arcgisscripting.pyc", line 12, in <module>
File "arcgisscripting.pyc", line 10, in __load
ImportError: DLL load failed: The specified module could not be found.
I use python 2.7 and arcgis 10.1 - feel free to ask if I've forgotten any useful information.
Can anyone tell me what I need to do to get the executable working properly?
Many thanks!

I had the same problem...
Since your users will have python/arcpy installed on their machines have your arcpy scripts in a data_files directory.
setup(windows=[script], data_files=[('scripts', glob(r'/path/to/scripts/*.py')], options=options)
Then call them using subprocess.Popen
import subprocess
subprocess.Popen(r'python "%s\scripts\autolim.py"' % self.basedir)
Popen is non-blocking so it won't freeze your GUI while the arcpy script runs.
If you want to print any print statements in your arcpy script change to
p = subprocess.Popen(r'python "%s\scripts\autolim.py"' % self.basedir, stdout=subprocess.PIPE)
while True:
line = p.stdout.readline()
if not line:
break
sys.stdout.write(line)
sys.stdout.flush()

I suggest you see this step: https://community.esri.com/t5/python-questions/using-py2exe-with-arcpy-it-can-be-done-easily/td-p/360520
You must add exclude in setup options and copy the site-packages path.
I have tried it and it works.

Related

gsutil not working if calling from pycharm with python and subprocess, "cannot import name _common"

I have written a python script to automatize some gsutil operations.
gsutil works fine if I run it by command line. But if I translate the same command with subprocess in python I get an error:
BUCKET_NAME = 'datastore-backup'
FOLDER_NAME = 'my_folder'
gcs_path = os.path.join('gs://', BUCKET_NAME, FOLDER_NAME)
files = subprocess.check_output(['gsutil', 'ls', gcs_path], stderr=sys.stdout)
print(files)
I get this error
Traceback (most recent call last):
File "/Users/dario/Downloads/google-cloud-sdk/bin/bootstrapping/gsutil.py", line 13, in <module>
import bootstrapping
File "/Users/dario/Downloads/google-cloud-sdk/bin/bootstrapping/bootstrapping.py", line 32, in <module>
import setup # pylint:disable=g-import-not-at-top
File "/Users/dario/Downloads/google-cloud-sdk/bin/bootstrapping/setup.py", line 55, in <module>
from googlecloudsdk.core import properties
File "/Users/dario/Downloads/google-cloud-sdk/lib/googlecloudsdk/core/properties.py", line 34, in <module>
from googlecloudsdk.core.util import times
File "/Users/dario/Downloads/google-cloud-sdk/lib/googlecloudsdk/core/util/times.py", line 55, in <module>
from dateutil.tz import _common as tz_common
ImportError: cannot import name _common
any help
I have solved this problem for good. The source of the issue is when you call either subprocess.check or os.system(, the gsutil cli would use the wrong python.
In my case gsutil uses a system python binary that is 2.7. I uncovered this issue by inserting a print(tz) statement in /Users/dario/Downloads/google-cloud-sdk/lib/googlecloudsdk/core/util/times.py. And it turns out that it is loading a Python2.7/site-packages version of dateutil.
So to fix this, you can specify the cloudsdk python binary via the following
export CLOUDSDK_PYTHON=<what-ever-python-distro-you-want>
pyCharm is a wonderful tool second to non. Hope this makes it easy for some to use the built-in runner/debugger of this powerful IDE.

program wont work after being compiled with py2exe

I wrote a program it works fine without any errors when I run it from the python interpreter, I then used py2exe to turn it in to an .exe but when I run it it does'nt work anymore... I get this error:
Traceback (most recent call last):
File "pass.py", line 1, in <module>
File "dropbox\__init__.pyc", line 3, in <module>
File "dropbox\client.pyc", line 22, in <module>
File "dropbox\rest.pyc", line 26, in <module>
File "pkg_resources.pyc", line 950, in resource_filename
File "pkg_resources.pyc", line 1638, in get_resource_filename
NotImplementedError: resource_filename() only supported for .egg, not .zip
Am I supposed to do something when using py2exe when I have downloaded modules imported into the program?
these are the modules imported :
import dropbox
import os
import getpass
from time import sleep
please help !
I fixed this problem using the solution found here
basically you modify ~line 26 in rest.py found in the dropbox library
to this:
try:
TRUSTED_CERT_FILE = pkg_resources.resource_filename(__name__, 'trusted-certs.crt')
except:
# if current module is frozen, use library.zip path for trusted-certs.crt path
# trusted-certs.crt must exist in same directory as library.zip
if hasattr(sys,'frozen'):
resource_name = sys.prefix
resource_name.strip('/')
resource_name += '/trusted-certs.crt'
TRUSTED_CERT_FILE = resource_name
else:
raise
and then place the trusted-certs.crt file also found in the dropbox library in the same folder as your executable

py2exe not finding modules already installed?

I'm trying to use p2exe to build an exe from a python script that uses pymodbus and twisted (with lots of underlying dependencies apparently). I can build the exe but it does not run properly. I'm trying to figure out what I am doing wrong setting up the environment. I'm confident it is not my script because I can run it just fine from the python command line interpreter.
My python script uses these modules...
from pymodbus.server.async import StartTcpServer
from pymodbus.datastore import ModbusSequentialDataBlock
from pymodbus.datastore import ModbusSlaveContext, ModbusServerContext
import sys
import logging
from twisted.internet.task import LoopingCall
I get this error on python setup1.py py2exe...
The following modules appear to be missing
['Crypto.PublicKey._fastmath', 'FCNTL', 'OpenSSL', 'OpenSSL.SSL', 'OpenSSL._util', 'PAM', 'System', 'System.IO.Ports', 'TERMIOS', '_scproxy',
'gmpy', 'idna', 'pkg_resources', 'pyasn1.codec.ber', 'pyasn1.error', 'pyasn1.type', 'queue', 'resource', 'service_identity', 'service_identity
.pyopenssl', 'twisted.python._initgroups', 'twisted.python.sendmsg']
It builds the exe. When I run the exe this happens...
C:\Users\jlaird\Desktop\slush\dbclienttest\dist>modbus_slave2.exe
Traceback (most recent call last):
File "modbus_slave2.py", line 1, in <module>
File "pymodbus\server\async.pyc", line 18, in <module>
File "pymodbus\internal\ptwisted.pyc", line 5, in <module>
File "twisted\conch\manhole_ssh.pyc", line 14, in <module>
File "twisted\conch\ssh\factory.pyc", line 15, in <module>
File "twisted\conch\ssh\transport.pyc", line 32, in <module>
File "twisted\conch\ssh\keys.pyc", line 20, in <module>
ImportError: No module named pyasn1.error
If I start python and do 'import pyasn1' it imports without error. I can also import twisted and pymodbus just fine. Python can reach it but not py2exe. Why?
Figured it out...for some reason the contents of the build\lib folder for pyasn1 was not copied into C:\Python27\Lib\site-packages. Only an egg was copied. So I moved the folder over into site-packages and py2exe built an executable that worked.

How to package psutil with py2exe?

The app is working fine on my development win8 environment, but when it is packaged with py2exe and run on the production machine it throw the exception:
"The procedure entry point RtlIdnToAscii could not be located in the dynamic link library ntdll.dll"
The detail content of the log file is
Traceback (most recent call last):
File "DataviewerBackupRestorer.py", line 6, in <module>
File "RestorController.pyc", line 7, in <module>
File "psutil\__init__.pyc", line 136, in <module>
File "psutil\_psmswindows.pyc", line 14, in <module>
File "_psutil_mswindows.pyc", line 12, in <module>
File "_psutil_mswindows.pyc", line 10, in __load
ImportError: DLL load failed: The specified procedure could not be found.
It seems that a dll required by psutil is missing during the package process. I have tried to add the py2exe options with
py2exe_options = {"py2exe":{"includes":['decimal', '_mssql', 'uuid', 'psutil', '_psutil_mswindows']}}
But it is not working. Any ideas? Thanks in advance!
The solution is to remove System DLLs from the project directory. When I added psutil to my application py2exe added a lot of system DLLs to my project. It worked correctly on my and some other computers, but failed on another one. Removing from the project the .dll files that were available in C:\Windows\System32 solved the issue.
Finally in my case the solution was to add:
'dll_excludes': [ "IPHLPAPI.DLL", "NSI.dll", "WINNSI.DLL", "WTSAPI32.dll"]
into the py2exe options in setup.py file.

Create standalone MoinMoin wiki executable

I'm trying to create a standalone, desktop version of a MoinMoin wiki so I can distribute it on a CDROM to people who may or may not have Python installed. I've tried both py2exe and bbfreeze with no luck. They both create an executable, but when that executable is run I get the same error from both:
C:\python_class\cdrom\bb-binary>wikiserver.exe
2011-08-22 15:06:21,312 WARNING MoinMoin.log:138 load_config for "C:\python_class\cdrom\bb-binary\wikiserverlogging.conf
" failed with "No section: 'formatters'".
2011-08-22 15:06:21,312 WARNING MoinMoin.log:139 using logging configuration read from built-in fallback in MoinMoin.log
module!
Traceback (most recent call last):
File "<string>", line 6, in <module>
File "__main__.py", line 128, in <module>
File "__main__wikiserver__.py", line 35, in <module>
File "MoinMoin/script/__init__.py", line 138, in run
File "MoinMoin/script/__init__.py", line 248, in mainloop
File "MoinMoin/wikiutil.py", line 1078, in importBuiltinPlugin
File "MoinMoin/wikiutil.py", line 1117, in builtinPlugins
File "MoinMoin/util/pysupport.py", line 81, in importName
ImportError: No module named server
Here is the setup.py script I used for py2exe:
from distutils.core import setup
import py2exe
includes = ["MoinMoin"]
excludes = []
packages = []
setup(options = {
"py2exe" : {
"includes" : includes,
"excludes" : excludes,
"packages" : packages,
"dist_dir" : "dist"
}
},
console=["wikiserver.py"])
And here is the setup.py script I used for bbfreeze:
from bbfreeze import Freezer
includes = ["MoinMoin.*"]
excludes = []
f = Freezer(distdir="bb-binary", includes=includes, excludes=excludes)
f.addScript("wikiserver.py")
f.use_compression = 0
f.include_py = True
f()
If anyone has any help or suggestions, I'd greatly appreciate it!
Thanks,
Doug
py2exe has limitations in identifying which modules to include, especially if they are imported conditionally. For example,
import module
on its own line will work, however,
if someCondition:
import module
won't. As is often the case with many large frameworks, MoinMoin only imports the modules it needs to use when it needs them. Unfortunately, you will need to tell py2exe to include these missing modules manually, and this is going to take some trial-and-error until you find all the ones you need.
See here for how to include modules manually.

Categories

Resources