Import custom arcpy modules in Pro 1.4 (from Python addin structure)

2945
11
Jump to solution
04-18-2017 05:55 PM
RebeccaStrauch__GISP
MVP Emeritus

I'm trying to test some of my custom tools, written for a ArcCatalog python addin.   This is my first attempt to use Pro, without the convenience and the power we have with ArcCatalog (but hoping the idea: Add Stand Alone Data Catalog Like ArcCatalog to ArcGIS Pro  will still happen so that this isn't as critical a test ....please vote up the idea! ).

I have several blahUtils.py  type scripts to separate/organize my common functions. These are located in my Scripts folder in my addin file structure and I import into my tools/scripts using

from blahUtils import *

from moreBlahUtils import *

# etc...

rather than in a library in the python folder....that is, keep the addin all together.

This structure works well in ArcCatalog running is as an built/installed addin or from the Toolbox/Tool used to create the addin.

Putting aside the differences between Python 2.x and 3.x for the time being, how would I import the utility python scripts within my main tool script?  I have read thru

Importing ArcPy—ArcPy Get Started | ArcGIS Desktop    and

Python migration from 10.x to ArcGIS Pro—ArcPy Get Started | ArcGIS Desktop   (no, I have not run the 2to3 tool yet)

but those seem to refer to fairly standard modules.  I would like to keep my scripts in the folder structure for my toolbox (i.e. the addin structure) if possible.

The error I am getting

Traceback (most recent call last):
  File "\\<server>\c$\Users\<user>\_MyPyAddins\dwcUpdateMasterFGDB\Install\scripts\01-CopyDWCMasterSDEtoFGDB.py", line 47, in <module>
    from ADFGUtils import *
  File "\\<server>\c$\Users\<user>\_MyPyAddins\dwcUpdateMasterFGDB\Install\scripts\ADFGUtils.py", line 134
    self.__dict__ = self"""
                         ^
SyntaxError: (unicode error) 'unicodeescape' codec can't decode bytes in position 188-189: truncated \UXXXXXXXX escape
Failed to execute (01-CopyDWCMasterSDEtoFGDB).

Is basically telling me it can not find the first custom script from ADFGutils import * I am trying to import. 

Any suggestions on where I need to put these and how I would refer to them?  Again, I prefer to keep in the same folder with/near my toolbox.

Thanks.

tagging PythonPython AddIns

0 Kudos
11 Replies
curtvprice
MVP Esteemed Contributor

Pro does not support Python addins. The only flavor it supports are those built in .NET.

RebeccaStrauch__GISP
MVP Emeritus

For the purposes of closing this thread, below is one way to add a single custom mod which is stored in same folder as the script that is running.  This is how my python addins are setup, so that is what I am testing.  Posting here in case others are trying to do the same.  I will start another post with this as a starting point, but hopefully to make it a bit more dynamic.  (I will come back and add a link to that once posted.)

This is a cut and paste from a large working tool...if something doesn't make sense, let me know...

import os
import sys
import arcpy
# --->  This is for python 3.5 in Pro 1.4.1

# shows messages for python window or tool
def myMsgs(message):
     arcpy.AddMessage(message)
     print(message)
     
scriptPath, scriptName = (os.path.dirname(sys.argv[0]), os.path.basename(sys.argv[0]))
scriptPathforVer = (scriptPath.replace("\\", "/"))
arcpy.env.scriptWorkspace = scriptPathforVer
myMsgs("Path {0} exists? {1}\n".format(scriptPathforVer, arcpy.Exists(scriptPathforVer)))
# not sure whether this is still needed....
sys.path.append(scriptPathforVer)

mymod = 'myCustomMod'    # for a mod myCustomMod.py in same folder as this script

import importlib.util
modPath = os.path.join(scriptPathforVer, (mymod + ".py"))
modPath = (modPath.replace("\\", "/"))
myMsgs("modpath {0} exists? {1}".format(modPath, arcpy.Exists(modPath)))     
try:
     spec = importlib.util.spec_from_file_location(mymod, modPath)
     # hardcodes the myCustomMod mod name.  Refer to mod is myCustomMod.afunc()
     myCustomMod = importlib.util.module_from_spec(spec)
     spec.loader.exec_module(vars()['myCustomMod'])
     myMsgs("Successfully loaded {0}\n".format(mymod))
except:
     myMsgs("-> Unable to load {0}\n".format(mymod))     


# test it with something in the mod, e.g.
#  myCustomMod.afunc()

hope this is helpful to someone.