errors importing custom tools from a ptyhon toolbox

1058
1
07-21-2014 05:03 AM
New Contributor

Hello Forum:

I'm getting errors importing custom tools from a ptyhon toolbox

My scenario si as follows:

I have developed 3 python toolboxes with some tools:

- PythonToolbox1 PT1 with Tool11 and Tool12  T11 T12

- PythonToolbox2 PT2 with Tool21 T21

- PythonToolbox3 PT3 with Tool31 T31

When calling T11 from T31 ( using importing arcpy.ImportToolbox(PT1)) the execution of T31 works fine

When calling T12 from T31 ( using importing arcpy.ImportToolbox(PT1)) the execution of T31 works fine

When calling T21 from T31 ( using importing arcpy.ImportToolbox(PT2)) the execution of T31 works fine

This is, when I call JUST ONE AND ONLY ONE tool, T31 works fine

But, if a tried to call more than one external tool from T31, I get errors:

When calling T11 and T12 from T31 ( using importing arcpy.ImportToolbox(PT1)) the execution of T31 works wrong (it executes T11 but not T12)

Traceback (most recent call last):

  File "<string>", line xxx, in execute

  File "C:\xxxx\PT1.pyt", line xx, in T12

AttributeError: Object: Tool or environment <T12> not found

When calling T11 and T21 from T31 ( using importing arcpy.ImportToolbox(PT1) and arcpy.ImportToolbox(PT2)) the execution of T31 works wrong (it executes T11 but not T21)

Traceback (most recent call last):

  File "<string>", line xxx, in execute

  File "C:\xxxx\PT2.pyt", line xx, in T21

AttributeError: Object: Tool or environment <T21> not found

I tried to use in T31 RemoveToolbox after using any call to a custom script,(and Import/Add Tool before calling them) but it still works wrong

It seems that one and only one external tool can be called from T31, but this make no sense.

Any ideas of this behaviour?

Thanks in advance

Antono

Reply
0 Kudos
1 Reply
New Contributor II

Antonio,

I have had very similar problems.  One way that usually makes this work (not that it is a very good way) is to import your toolboxes (in the correct order) from the python command window in ArcMap.  This is not ideal, but usually gets things to work.

I have a similar setup for some tools that I have create, lets call them BaseTools and CompositeTools.  The CompositeTools call tools from BaseTools, but BaseTools are all stand alone, they do not have dependencies on each other, nor on any tools other than Esri tools.  These tools are built within a Python site package, and distributed using this technique.  This makes the PYT files appear as system toolboxes in ArcMap in 10.2, it doesn't work in 10.0 or 10.1, but it will make things consistent, and you can easily add the PYT files by calling a custom function on the site package: see below.

To help make this work consistently here is what I do:

  • Add a method to the root of my site package called "add_toolbox"  The job of this method is to figure out where the PYT file is, check to see if it is already imported (remove it if it is) and then import it, so it looks like this (I put the other functions that I call at the end, I couldn't get them to paste here correctly) (also, I am importing arcpy within my function, but that is b/c of dependencies that I have so you may not do that there):

def add_toolbox():

    import arcpy

    ## List toolboxes and see if eaglepods6 is already installed

    eagle_pods_6_toolbox = arcpy.ListToolboxes("basetools")

    if len(eagle_pods_6_toolbox) == 1:

        arcpy.RemoveToolbox(_get_composite_toolbox_path())

        arcpy.RemoveToolbox(_get_toolbox_path())

    arcpy.AddToolbox(_get_toolbox_path())

    arcpy.AddToolbox(_get_composite_toolbox_path())

    return

  • This is where it gets really strange, so this works great because I now have a function to load my toolboxes, this makes it easy to call from the command line, or from inside a python script that is using my tools, but it does not fix the one tool depending on the other tool problem.  To get that to work I had to add the following to my CompositeTools PYT file:

import arcpy

import my_library

my_library.add_core_toolbox()

  • This function "add_core_toolbox" is almost the same as the above add toolbox function, but instead of adding both toolboxes (Composite and Base) it only adds the Base.  This ensures that when ArcMap is opening and loading PYTs, when it gets to the Composite one, it will force the Base one to load.  So my add_core_toolbox looks like this:

def add_core_toolbox():

    import arcpy

    ## List toolboxes and see if eaglepods6 is already installed

    eagle_pods_6_toolbox = arcpy.ListToolboxes("basetools")

    if len(eagle_pods_6_toolbox) == 1:

        arcpy.RemoveToolbox(_get_toolbox_path())

    arcpy.AddToolbox(_get_toolbox_path())

    return

I always make sure that I list the toolboxes, and remove the tool if it already exists.  This was added after trial and error, and seems to help ensure that the toolbox is loaded only once, even though they are always coming from the same path (in site packages).  I have never been able to get this to work outside of the special folder in site packages that Esri uses to load system tools.  But using the code above, it does seem to work well in 10.0 - 10.2, which is nice.

Other functions used above:

def _get_toolbox_path():

    import os.path

    return os.path.join(os.path.dirname(__file__), "ESRI", "TOOLBOXES", "Base Tools.pyt")

def _get_composite_toolbox_path():

    import os.path

    return os.path.join(os.path.dirname(__file__), "ESRI", "TOOLBOXES", "Composite Tools.pyt")

Essentially there is an issue with the way/order in which PYT files are read in by the system, Esri already knows about it and is working on a fix, but in the meantime, this is the only way I know of to get interdependent PYT files to work.