Using Py2exe with Arcpy- It can be done easily!

8656
9
08-19-2015 08:14 AM
RachaelJohnson
Occasional Contributor

I recently finished a stand alone Python program that uses Arcpy extensively.  I wanted to package and distribute it as an executable so my users would have minimal problems trying to get the program working.  My program uses third-party libraries and I needed to update numpy on all the computers I tried to use it on.  The Tcl/Tk package was out of date on one of the computers and trying to update it was a nightmare.  Even though people using my program already have Python because they have ArcGIS, I really needed to get my program into an executable so my users would not have to endure the headache of setting up their Python environment to run my program. 

Cue Py2exe.  I set it up, ran my .exe, and got an error immediately:  "arcpy module could not be found" or something to that effect.  Well, crap. 

A bit of Internet searching did not turn up the results I wanted.  There were some complicated workarounds, such as calling the arcpy module in a subprocess, creating and using a wrapper script, or rewrite the script entirely.​ Someone even said that it just can't be done. Well, it can, and the solution is actually very simple, elegant (in my opinion), and requires very little extra effort by the user and the developer. 

Arcpy isn't packaged with the rest of the files when the executable is made, and forcing it to package the module is sure to be a gross violation of the ArcGIS user agreement.  Every user of the program will already have the arcpy module somewhere on their computer, so to get the executable to work, we just need to tell the program where to look for the arcpy module.  Unfortunately, the location of the arcpy module is likely to be different on everyone's computer.  Fortunately, the arcpy module isn't located with the rest of the Python modules anyway!  Instead, a .PTH file tells the program where to find the module.  We can make this work for us with Py2exe.

1.  Exclude "arcpy" from the Py2exe setup.py script. 

I'm not 100% sure this is necessary, to be honest.  There's no harm in doing it though.

options = {"py2exe": {"excludes": ["arcpy"]}}
setup(console=['MyProgram.py'], options=options)

2. Add the executable directory + "\\site-packages" to the Python site directory in the main code of MyProgram.py.

sys.executable gives the file path of the Python interpreter.  In this case, the Python interpreter is the executable.  The .PTH file needs to go into a folder called "site-packages" in order for the arcpy module to import correctly.  (You will add the site-packages folder manually to the dist folder after Py2exe has completed its job.) If you're not using Windows, change the backslashes to a single forward slash, ie + "/site-packages".  I also added the code to any script that would be running as a separate process, just in case.

from site import addsitedir
from sys import executable
from os import path
interpreter = executable
sitepkg = path.dirname(interpreter) + "\\site-packages"
addsitedir(sitepkg)

3. Run Py2exe as usual.

4. Add a "site-packages" folder to the "dist" folder.

5. Navigate to the GIS-installed Python folder, usually C:/Python27/ArcGIS10.x/Lib/site-packages

6. Copy the "Desktop10.x" PTH file and paste it into the "site-packages" folder in the "dist" directory for your application.

That's it.  The executable should load the arcpy module now. 

Instruct your users to copy the "Desktop10.x" PTH file into the executable's "site-packages" folder prior to running the application for the first time and it should work for them, too.

9 Replies
SteveXu
New Contributor III

I followed your instruction, and sill got the same traceback and error:

Traceback (most recent call last):

  File "JoinTaxParcelToAddress_1.py", line 9, 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: %1 is not a valid Win32 application.

I couldn't completely understand the second step "2. Add the executable directory + "\\site-packages" to the Python site directory in the main code of MyProgram.py. Would you please explain the second step further ? I'm using ArcGIS 10.2 and Python 2.7. Thank you very much.

0 Kudos
JeffSegal
New Contributor III

Was anyone ever able to get this to work properly?  Rachael Johnson​?

I get the same error that Steve Xu reported above ?

0 Kudos
JosephMcFadden
New Contributor

It works, thanks Rachael.  I am using ArcGIS 10.4 with Python 2.7. Initially received the following error when running the resulting executable

.

  File "C:\Program Files (x86)\ArcGIS\Desktop10.4\ArcPy\arcpy\arcobjects\mixins.
py", line 22, in <module>
    import xml.etree.ElementTree
ImportError: No module named etree.ElementTree

Python 2.7 includes xml.etree.ElementTree, so this error seemed odd.  Though my script does not utilize xml, I included the import for it prior to the import of arcpy, which corrected all.

   ...

   import xml.etree.ElementTree

   import arcpy

   ....

0 Kudos
SteveXu
New Contributor III

Hi Rachael:

I'm glad to hear it works for Joseph.

I'm looking back your instruction, and successfully made my exe file. However, when I ran my exe, I received this error "ImportError: No module named arcpy". Would you please instruct me how "to copy the "Desktop10.x" PTH file into the executable's "site-packages" folder prior to running the application for the first time"? What is the "Desktop10.x" PTH file? I'm using ArcGIS Desktop 10.2. Thank you.

0 Kudos
SteveXu
New Contributor III

Hi Rachael:

I found desktop10.2.pth file, and did what you suggested. However, still received the same error. Appreciate any suggestions. Thanks 

0 Kudos
NicoleKamp
New Contributor

Hello! I am using ArcGIS 10.4.1. and I cannot find this "Desktop10.x" PTH file. There is only one for ArcGIS 10.4.1. and if I copy the Desptop10.4.pth into site-packages and run the exe File, it still writes that there is no arcpy module. Can you maybe help me with this problem?

Thanks, 

Niki

0 Kudos
ethangranger1
New Contributor

it is important to note that the lines from step 2 must be ABOVE the import arcpy line.

Also, similar to Joseph's issue, i had to import xml.tree.ElementTree AND uuid AND numpy (even for a simply print 'Hello World') to make this work.

0 Kudos
LaurenPeckman
New Contributor III

I follow these steps and an executable is created. I made sure that step 2 becomes the first few lines of MyProgram.py. After the executable is created, I copy & paste the Desktop10.4.pth file into the dist/site-packages folder, and here's what happens:  

-py2exe readout says: 
"The following modules appear to be missing
['_scproxy', '_sysconfigdata', 'sitecustomize', 'usercustomize']"
-Black terminal window opens & closes quickly when I click the resulting MyProgram.exe. It's so fast, I can't capture a screenshot of it. 

I've no idea where those modules are, why they are missing, are they required? Is it ok for them to remain missing? No idea on that one. 

2 other ideas: 
1. 

I'm an ArcGIS10.4 user running python from: ...:\Python27\ArcGISx6410.4

But the .PTH file in the instructions, the one to copy & paste into the resulting dist/site-packages folder after the executable is created? That's in ...:\Python27\ArcGIS10.4\Lib\site-packages

Perhaps that's the problem? If so, I don't know what to do about it. If not ... 

2. 
I had to exclude a whole list of DLLs to get the py2exe to work without "missing dlls" list at the end. So here's my code for the setup.py: 

```

from distutils.core import setup
import py2exe


options = {
    "py2exe": {"excludes": ["arcpy"],
               "dll_excludes": ["USER32.dll",
                                "IMM32.dll",
                                "SHELL32.dll",
                                "KERNEL32.dll",
                                "COMDLG32.dll",
                                "ADVAPI32.dll",
                                "WS2_32.dll",
                                "GDI32.dll",
                                "ole32.dll",
                                "OLEAUT32.dll",
                                "COMCTL32.dll"]}}

setup(console=['MyProgram.py'], options=options)

I don't know what to do now. Help, please! 

0 Kudos
YeremiaSihombing
New Contributor

I have tried and it works so well.

Just make sure you change the path in environment variables to C:\Python27\ArcGIS10.X\Scripts and copy the "Desktop10.x" PTH.

0 Kudos