Set default values for python toolbox parameters

6954
1
02-13-2015 11:51 AM
SuzanneRoulston-Doty
New Contributor II

I am sure this is already out there but I could not find it so I thought I would share this code sample for storing and setting python toolbox tool parameter values using python pickles.  I am not a programmer so any feedback for doing this a better way is always appreciated.

import arcpy, pickle, os, sys

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

        # List of tool classes associated with this toolbox
        self.tools = [Tool]
   
class Tool(object):
    def __init__(self):
        """Define the tool (tool name is the name of the class)."""
        self.label = "Tool"
        self.description = ""
        self.canRunInBackground = False
       
    def getParameterInfo(self):
        """Define parameter definitions"""
       
    #set default values for tool parameters
    scriptPath = sys.path[0]
    test_val = pickle.load(open(scriptPath + "\\test_params.txt", "rb"))   
       
    #First parameter
    param0 = arcpy.Parameter(
        displayName="Input Feature Class",
        name="in_fc",
        datatype=["Feature Class"],
        parameterType="Required",
        direction="Input")

    param0.value = test_val['param0']
   
    params = [param0]
    return params

    def isLicensed(self):
        """Set whether tool is licensed to execute."""
        return True

    def updateParameters(self, parameters):
        """Modify the values and properties of parameters before internal
        validation is performed.  This method is called whenever a parameter
        has been changed."""
        return

    def updateMessages(self, parameters):
        """Modify the messages created by internal validation for each tool
        parameter.  This method is called after internal validation."""
        return

    def execute(self, parameters, messages):
        """The source code of the tool."""
   
        scriptPath = sys.path[0]
        test_val = {}
        test_val = {"param0": parameters[0].valueAsText}
        pickle.dump (test_val, open(scriptPath + "\\test_params.txt", "wb"))

        return
1 Reply
Luke_Pinner
MVP Regular Contributor

Pickle is one way. I use JSON though as it's more "human readable".

import os, arcpy, json

class Tool(object):
    def __init__(self):
        #Save settings in %APPDATA%/arcgistools/{module}.settings
        setdir = os.path.join(os.environ['APPDATA'], 'arcgistools')
        if not os.path.exists(setdir):
            os.makedirs(setdir)
        self._settings = os.path.join(setdir, __name__+'.settings') 
        self._toolname = type(self).__name__
        
    def get_settings(self):
        # Structure of settings dict is {toolname1: {paramname: paramvalue}, toolname2: {paramname: paramvalue}}
        try:
            return json.load(open(self._settings, 'r'))[self._toolname]
        except (OSError, KeyError, ValueError,IOError):
            return {}

    def save_settings(self, settings):
        # Don't overwrite other tools settings
        try:
            existing = json.load(open(self._settings, 'r'))
        except (OSError, KeyError, ValueError, IOError):
            existing = {}
        existing[self._toolname]=settings
        json.dump(existing, open(self._settings, 'w'))

class Test1(Tool):
    def __init__(self):
        Tool.__init__(self)

        self.label = "Tool1"
        self.description = ""
        self.canRunInBackground = False   
        
    def getParameterInfo(self):

        """Define parameter definitions"""
        settings = self.get_settings()
        
        #First parameter
        param0 = arcpy.Parameter(
            displayName="Input Feature Class",
            name="in_fc", #I use param.name as dict key
            datatype=["Feature Class"],
            parameterType="Required",
            direction="Input")

        param0.value = settings.get(param0.name, '')
        params = [param0]
        return params        

    def execute(self, parameters, messages):
        """The source code of the tool."""
        settings = {}
        for param in parameters:
            settings[param.name] = param.valueAsText
        self.save_settings(settings)
        return
        
class Test2(Tool):
    def __init__(self):
        Tool.__init__(self)

        self.label = "Tool2"
        # etc...








0 Kudos