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?
Figure 1. Desired outcome.
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...
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!
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]
Thanks Hayden, I tried your suggestion however I still see that the toolbox is 'broken' and when checking the syntax I get an error.
Figure 1. Broken toolbox.
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]