Select to view content in your preferred language

Python Toolbox: how to return string to the calling ArcGIS Pro SDK

802
2
Jump to solution
02-21-2024 06:18 AM
nadja
by
Frequent Contributor

I've got an Add-In (Dockpane) created with the .NET SDK for ArcGIS Pro, in which I'm executing a Python-toolbox. As long as I don't have to return a value into my .NET SDK, it works fine. But I'm stuck when I try to return a value, even just a string, from my python toolbox into the calling scope. Could anyone help me? 

 

That's my python-script:

import arcpy
if arcpy.GetLogHistory():
   arcpy.SetLogHistory(False)
if arcpy.GetLogMetadata():
    arcpy.SetLogMetadata(False)
from tkinter import messagebox
from osgeo import gdal
import os
import ast

from arcpy.arcobjects import convertArcObjectToPythonObject
import sys


class Toolbox(object):
    def __init__(self):
        """Define the toolbox (the name of the toolbox is the name of the
        .pyt file)."""
        self.label = "Toolbox"
        self.alias = "toolbox"

        # List of tool classes associated with this toolbox
        self.tools = [ParcsVectors]

def load_vector():
    try: 
        messagebox.showinfo(title="test", message="Hello - this message is from a TEST Python script")
        return "test"

    except Exception as err:
       messagebox.showinfo(title="Load vectors failed", message="Exception: " + str(err))


class ParcsVectors(object):
    def __init__(self):
        """Define the tool (tool name is the name of the class)."""
        self.label = "ParcsVectors"
        self.description = ""
        
    def getParameterInfo(self):
        """Define parameter definitions"""
        result = arcpy.Parameter(
            displayName="Output Features",
            name="out_features",
            datatype="GPString",
            parameterType="Required",
            direction="Output")

        params = [result]

        return params

    def isLicensed(self):
        return True

    def updateParameters(self, parameters):
        return

    def updateMessages(self, parameters):
        return

    def execute(self, parameters, messages):
        # parameters[0] = load_vector()
        result = load_vector()
        messagebox.showinfo(title="testing", message= result)
        arcpy.SetParameter(0, result)
        return

The messagebox shows the correct result. But it is not returned to 

var gpResult = Geoprocessing.ExecuteToolAsync(toolboxPath, null, null, null, null, GPExecuteToolFlags.AddToHistory); 
gpResult.Wait();

what do I need to change in my python script, so that the return value is actually returned?

0 Kudos
1 Solution

Accepted Solutions
davidmillar
New Contributor
  1. Define an Output Parameter in Python: In your Python toolbox, you need to define an output parameter. This is done in the getParameterInfo method of your tool class. The parameter’s direction should be set to "Output" and parameterType to "Derived".
  2. Set the Output Parameter in Python: In the execute method of your tool class, you need to set the value of the output parameter. You can do this using the arcpy.SetParameter function.
  3. Access the Output Parameter in .NET: In your .NET code, you can access the output parameter from the result of the Geoprocessing. ExecuteToolAsync method. The IGPResult object returned by this method has a ReturnValue property that contains the output parameter.

Here’s a simplified example:

# Python Toolbox
class MyTool(object):
    def getParameterInfo(self):
        # Define output parameter
        param = arcpy.Parameter(
            displayName="Output",
            name="out_param",
            datatype="GPString",
            parameterType="Derived",
            direction="Output"
        )
        return [param]

    def execute(self, parameters, messages):
        # Set output parameter
        arcpy.SetParameter(0, "Hello, World!")

 

// .NET SDK
public async Task RunMyToolAsync()
{
    var result = await Geoprocessing.ExecuteToolAsync("my_toolbox\\my_tool");
    var output = result.ReturnValue;  // "Hello, World!"
}

 

Please replace "my_toolbox\\my_tool" with the actual name of your toolbox and tool.
 

View solution in original post

0 Kudos
2 Replies
davidmillar
New Contributor
  1. Define an Output Parameter in Python: In your Python toolbox, you need to define an output parameter. This is done in the getParameterInfo method of your tool class. The parameter’s direction should be set to "Output" and parameterType to "Derived".
  2. Set the Output Parameter in Python: In the execute method of your tool class, you need to set the value of the output parameter. You can do this using the arcpy.SetParameter function.
  3. Access the Output Parameter in .NET: In your .NET code, you can access the output parameter from the result of the Geoprocessing. ExecuteToolAsync method. The IGPResult object returned by this method has a ReturnValue property that contains the output parameter.

Here’s a simplified example:

# Python Toolbox
class MyTool(object):
    def getParameterInfo(self):
        # Define output parameter
        param = arcpy.Parameter(
            displayName="Output",
            name="out_param",
            datatype="GPString",
            parameterType="Derived",
            direction="Output"
        )
        return [param]

    def execute(self, parameters, messages):
        # Set output parameter
        arcpy.SetParameter(0, "Hello, World!")

 

// .NET SDK
public async Task RunMyToolAsync()
{
    var result = await Geoprocessing.ExecuteToolAsync("my_toolbox\\my_tool");
    var output = result.ReturnValue;  // "Hello, World!"
}

 

Please replace "my_toolbox\\my_tool" with the actual name of your toolbox and tool.
 
0 Kudos
nadja
by
Frequent Contributor

Thank you @davidmillar, the python script is the needed solution. the NET SDK solution however isn't correct, as there is nor ReturnValue. But in this post is the correct NET SDK solution.

0 Kudos