Can tools from imported scripts in a Python Toolbox be placed into Toolsets?

598
3
09-18-2023 04:18 PM
ColinLindeman
New Contributor II

Hello, I'd like to create a python toolbox for ArcPro that imports all of its tools from scripts in separate folders and I want these tools placed in toolsets. I may even put toolsets within toolsets. This way I can manage the python code more easily and avoid having all of it in one python script.

It appears that when a tool is imported as a script from another directory, the tool's self.category field is not honored and the tool is placed at the toolbox root. Any ideas on how to implement this? Did I do something incorrectly or will I need to request help/fix from ESRI?

This is the desired outcome when viewd in ArcGIS Pro. This setup does not import the script files but contains all tools within one python file.This is the desired outcome when viewd in ArcGIS Pro. This setup does not import the script files but contains all tools within one python file.Figure 1. Desired outcome.

This screenshot shows what happens when the tools are imported. The self.category settings appear to be ignored.This screenshot shows what happens when the tools are imported. The self.category settings appear to be ignored.Figure 2. Actual outcome.

Here is  the code to reproduce the issue as seen in Figure 2. You will need to setup the folder structure as needed (see screenshots above).

 

import arcpy
import os
import sys
myScripts = os.path.join(os.path.dirname(__file__), "scripts","Import")
sys.path.append(myScripts)
from scripts.Import import First

myScripts = os.path.join(os.path.dirname(__file__), "scripts","Export")
sys.path.append(myScripts)
from scripts.Export import Second
from scripts.Export import Third

class Toolbox(object):
    def __init__(self):
        self.label = u'Example_Toolbox'
        self.alias = ''
        self.tools = [First, Second, Third]
class FirstTool(object):

    def __init__(self):
        self.label = u'First Tool'
        self.description = u''
        self.canRunInBackground = False
        self.category = "Import"

    def getParameterInfo(self):
        return

    def execute(self, parameters, messages):
        pass
class SecondTool(object):

    def __init__(self):
        self.label = u'Second Tool'
        self.description = u''
        self.canRunInBackground = False
        self.category = "Export"

    def getParameterInfo(self):
        return

    def execute(self, parameters, messages):
        pass
class ThirdTool(object):

    def __init__(self):
        self.label = u'Third Tool'
        self.description = u''
        self.canRunInBackground = False
        self.category = "Export"

    def getParameterInfo(self):
        return

    def execute(self, parameters, messages):
        pass

 

 

This post was helpful in setting toolsets (self.category) https://community.esri.com/t5/python-questions/python-toolbox-toolset/m-p/636796/thread-id/49579

This post was helpful in importing scripts from other folders https://pro.arcgis.com/en/pro-app/latest/help/analysis/geoprocessing/share-analysis/packaging-python...

 

0 Kudos
3 Replies
JonSnow06
New Contributor

Welcome to the community, ColinLindeman!

Thank you for sharing your question about importing tools from scripts in a Python Toolbox. I understand that you're facing challenges with tool placement when using separate folders and toolsets.

Based on the information and code you provided, it seems that the self.category settings are not being honored when importing the tools as scripts. To resolve this issue, I recommend reaching out to the ESRI support team or posting your question in the Python Questions section of the community.

Other community members may also offer their experiences and suggestions to help you find a solution. Feel free to provide any additional details or ask for further clarification.

We're glad to have you here, and we look forward to assisting you further!

0 Kudos
HaydenWelch
Occasional Contributor

You need to import the tool objects, but currently you're importing the module:

import arcpy
import os
import sys
myScripts = os.path.join(os.path.dirname(__file__), "scripts","Import")
sys.path.append(myScripts)
from scripts.Import import First.FirstTool as First

myScripts = os.path.join(os.path.dirname(__file__), "scripts","Export")
sys.path.append(myScripts)
from scripts.Export import Second.SecondTool as Second
from scripts.Export import Third.ThirdTool as Third

class Toolbox(object):
    def __init__(self):
        self.label = u'Example_Toolbox'
        self.alias = ''
        self.tools = [First, Second, Third]

 

If you want more info on this, I have a recent post here about managed toolboxes that use python's m...

0 Kudos
ColinLindeman
New Contributor II

Thanks Hayden, I tried your suggestion however I still see that the toolbox is 'broken' and when checking the syntax I get an error.

error1.JPG
Figure 1. Broken toolbox.

syntaxerror.jpg

 Figure 2. Syntax Error.


I also tried the renaming the folders to atools and btools and trying a different way to import however I was met with no luck:

import arcpy
import os
import sys
myScripts = os.path.join(os.path.dirname(__file__), "scripts","atools")
sys.path.append(myScripts)
import scripts.atools.First.FirstTool as First

myScripts = os.path.join(os.path.dirname(__file__), "scripts","btools")
sys.path.append(myScripts)
import scripts.btools.Second.SecondTool as Second
import scripts.btools.Third.ThirdTool as Third

class Toolbox(object):
    def __init__(self):
        self.label = u'Example_Toolbox'
        self.alias = ''
        self.tools = [First, Second, Third]

 

0 Kudos