Validation is everything that happens before a tool's OK button is clicked. When creating your own custom tools, validation allows you to customize how parameters respond and interact to values and each other. Validation is performed with a block of Python code that is used to control tool behavior.
To learn more about validation, see Understanding validation in script tools.
In a Python toolbox, every tool parameter has an associated Parameter object with properties and methods that are useful in tool validation. In a Python toolbox, parameters are defined in the getParameterInfo method of the tool class. The behavior of those parameters, and how they interact with each other and inputs, is validated according to the updateParameters method of the tool class.
- Updating schema in a Python toolbox
- License behavior in a Python toolbox
- Postprocessing validation in a Python toolbox
Access the tool parameters
Parameter objects form the foundation of how parameters are defined and interact in a Python toolbox. The standard practice is to create the list of parameters in the tool class's getParameterInfo method, as shown in the code below.
def getParameterInfo(self):
#Define parameter definitions
# First parameter
param0 = arcpy.Parameter(
displayName="Input Features",
name="in_features",
datatype="GPFeatureLayer",
parameterType="Required",
direction="Input")
return [param0]
For more about defining parameters in a Python toolbox, see Defining parameters in a Python toolbox.
Parameter object
Methods
Method name | Usage description |
---|---|
setErrorMessage(message) | Marks the parameter as having an error () with the supplied message. Tools do not execute if any of the parameters have an error. |
setWarningMessage(message) | Marks the parameter as having a warning () with the supplied message. Unlike errors, tools do execute with warning messages. |
setIDMessage(messageType, messageID, {AddArgument1}, {AddArgument2}) | Allows you to set a system message. The arguments are the same as the AddIDMessage function. |
clearMessage() | Clears out any message text and sets the status to informative (no error or warning). |
hasError() | Returns true if the parameter contains an error. |
hasWarning() | Returns true if the parameter contains a warning. |
isInputValueDerived() | Returns true if the tool is being validated inside a model and the input value is the output of another tool in the model. |
Properties
Property name | Read/write | Value | Description |
---|---|---|---|
name | Read-only | String | The parameter name. |
direction | Read-only | String: "Input", "Output" | Input/Output direction of the parameter. |
datatype | Read-only | String | For a list of parameter data types, see Defining parameter data types in a Python toolbox. |
parameterType | Read-only | String: "Required", "Optional", "Derived" | The parameter type. |
parameterDependencies | Read/write | Python list | A list of indexes of each dependent parameter. |
value | Read/write | Value object | The value of the parameter. |
defaultEnvironmentName | Read-only | String | The default environment setting. |
enabled | Read/write | Boolean | False if the parameter is unavailable. |
altered | Read-only | Boolean | True if the user has modified the value. |
hasBeenValidated | Read-only | Boolean | True if the internal validation routine has checked the parameter. |
category | Read/write | String | The category of the parameter. |
schema | Read-only | Schema object | The schema of the output dataset. |
filter | Read-only | Filter object | The filter to apply to values in the parameter. |
symbology | Read/write | String | The path to a layer file (.lyrx) used for drawing the output. |
message | Read-only | String | The message to be displayed to the user. See setErrorMessage and setWarningMessage above. |
Although many Parameter object properties are read/write, most of these properties can only be set or modified when you initially create or modify the object. Several properties, including name, displayName, datatype, direction, and parameterType, establish the characteristics of a tool and cannot be modified during validation methods (such as updateMessages and updateParameters).
parameterDependencies
You typically set parameter dependencies for use by the Schema object. There are two cases in which the dependencies may already be set in the getParameterInfo method of the tool.
- Para un parámetro de dataset de salida con tipo derivado, la dependencia es el índice del parámetro del que se deriva la salida.
- Para determinados tipos de datos de entrada, la dependencia es el índice del parámetro que contiene la información utilizada por el control, según se muestra en la tabla a continuación.
Tipo de datos de parámetro | Tipo de datos del parámetro Dependant |
---|---|
Unidad de área (GPArealUnit) | Un dataset geográfico utilizado para determinar las unidades por defecto. Por ejemplo, se puede utilizar el tipo de datos Capa de entidades (GPFeatureLayer), Capa ráster (GPRasterLayer), Conjunto de entidades (GPFeatureRecordSetLayer) o Conjunto de registro (GPRecordSet). |
Campo (Field) | La tabla que contiene los campos. Por ejemplo, se puede utilizar el tipo de datos Vista de tabla (GPTableView), Capa de entidades (GPFeatureLayer), Capa ráster (GPRasterLayer), Conjunto de entidades (GPFeatureRecordSetLayer) o Conjunto de registro (GPRecordSet). |
Asignaciones de campo (GPFieldMapping) | Un conjunto de campos en una o varias tablas de entrada. Por ejemplo, se puede utilizar el tipo de datos Vista de tabla (GPTableView), Capa de entidades (GPFeatureLayer), Capa ráster (GPRasterLayer), Conjunto de entidades (GPFeatureRecordSetLayer) o Conjunto de registro (GPRecordSet). |
Tabla de valores geoestadística ( GPGAValueTable) | Una tabla de los datasets y campos que se van a utilizar en las herramientas de Geostatistical Analyst. Utilice el tipo de datos Capa geoestadística (GPGALayer). |
Unidad lineal (GPLinearUnit) | Un dataset geográfico utilizado para determinar las unidades por defecto. Por ejemplo, se puede utilizar el tipo de datos Capa de entidades (GPFeatureLayer), Capa ráster (GPRasterLayer), Conjunto de entidades (GPFeatureRecordSetLayer) o Conjunto de registro (GPRecordSet). |
Configuración de jerarquía de Network Analyst (GPNAHierarchySettings) | El dataset de red que contiene la información de jerarquía. Utilice el tipo de datos Dataset de red (DENetworkDataset). |
Modo de viaje de red (NetworkTravelMode) | Lista de modos de viaje. Utilice el tipo de datos Fuente de datos de red (GPNetworkDataSource), Dataset de red (DENetworkDataset) o Capa de dataset de red (GPNetworkDatasetLayer). |
Expresión SQL (GPSQLExpression) | La tabla que contiene los campos. Por ejemplo, se puede utilizar el tipo de datos Vista de tabla (GPTableView), Capa de entidades (GPFeatureLayer), Capa ráster (GPRasterLayer), Conjunto de entidades (GPFeatureRecordSetLayer) o Conjunto de registro (GPRecordSet). |
Dependencies are typically set in the getParameterInfo method:
def getParameterInfo(self):
#Define parameter definitions
# First parameter
param0 = arcpy.Parameter(
displayName="Input Features",
name="in_features",
datatype="GPFeatureLayer",
parameterType="Required",
direction="Input")
# Second parameter
param1 = arcpy.Parameter(
displayName="Sinuosity Field",
name="sinuosity_field",
datatype="Field",
parameterType="Optional",
direction="Input")
param1.value = "sinuosity"
# Third parameter
param2 = arcpy.Parameter(
displayName="Output Features",
name="out_features",
datatype="GPFeatureLayer",
parameterType="Derived",
direction="Output")
param2.parameterDependencies = [param0.name]
param2.schema.clone = True
params = [param0, param1, param2]
return params
value
This is the value of the parameter that the user entered or you set programmatically. You can set the value in the getParameterInfo method, in which case it serves as the initial default value for the parameter. You can also set the value in updateParameters in response to user input, as shown below.
def updateParameters(self, parameters):
# Set the default distance threshold to 1/100 of the larger of the width
# or height of the extent of the input features. Do not set if there is no
# input dataset yet, or the user has set a specific distance (Altered is true).
#
if parameters[0].valueAsText:
if not parameters[6].altered:
extent = arcpy.Describe(parameters[0]).extent
if extent.width > extent.height:
parameters[6].value = extent.width / 100
else:
parameters[6].value = extent.height / 100
return
A parameter's value property returns an object unless the parameter isn't populated in which case value returns None. To ensure that a parameter is populated, use an if check prior to using its value.
The code snippet below tests whether the value is equal to the string "Get Spatial Weights From File". This test works because the parameter data type is a string.
# If the option to use a weights file is selected, enable the
# parameter for specifying the file, otherwise disable it
if parameters[3].value: # check that parameter has a value
if parameters[3].value == "Get Spatial Weights From File":
parameters[8].enabled = True
else:
parameters[8].enabled = False
Since a Value object does not support string manipulation, use the Value object's value property whenever a string is to be manipulated or parsed. The code sample below uses the os.path.dirname method to return the directory from a dataset.
if parameters[0].value:
workspace = os.path.dirname(parameters[0].value.value)
Nota:
With the exception of Describe, don't use methods that take a catalog path, such as ListFields, in validation. The dataset may not exist when your tool is validated in ModelBuilder, and the method may fail or give unexpected results.
In the specific case of ListFields, the Describe object's fields property will provide the equivalent information.
Nota:
Don't set a parameter value in updateMessages(), since the value will not be validated by the internal validation routine.
altered
altered is true if the value of a parameter is changed—by entering an output path, for example. Once a parameter has been altered, it remains altered until the user empties (removes) the value in which case it returns to an unaltered state. Programmatically changing a value with validation code will change the altered state. That is, if you set a value for a parameter, the altered state of the parameter will be updated.
altered is used to determine whether you can change the value of a parameter. As an example, suppose a tool has a feature class parameter and a keyword parameter. If the feature class contains points or polygons, the keywords are RED, GREEN, and BLUE, and if lines, ORANGE, YELLOW, PURPLE, and WHITE.
Suppose the user enters a point feature class. If the keyword parameter is unaltered, you set the value to RED, since it's the default value.
If a line feature class is entered, you set the default value to ORANGE as long as the keyword parameter is unaltered.
However, if the keyword parameter has been altered by the user (that is, the keyword is set to GREEN), do not reset the keyword. The user has made their choice (GREEN) and you don't know their intention. They may change the feature class so that GREEN is valid or they may change the keyword (to PURPLE, for example). Since GREEN isn't a member of the set of keywords you created for lines, internal validation flags the parameter an error. Then the user has two options: change the input feature class or change the keyword.
if not parameters[2].altered:
parameters[2].value = "POINT"
hasBeenValidated
hasBeenValidated is false if a parameter's value has been modified by the user since the last time updateParameters and internal validate were called. Once internal validate has been called, geoprocessing automatically sets hasBeenValidated to true for every parameter.
hasBeenValidated is used to determine whether the user has changed a value since the last call to updateParameters. You can use this information in deciding whether to do your own checking of the parameter.
def updateParameters(self, parameters):
# Set the default distance threshold to 1/100 of the larger of the width
# or height of the extent of the input features. Do not set if there is no
# input dataset yet, or the user has set a specific distance.
#
if parameters[0].valueAsText:
if parameters[6].hasBeenValidated:
extent = arcpy.Describe(parameters[0]).extent
if extent.width > extent.height:
parameters[6].value = extent.width / 100
else:
parameters[6].value = extent.height / 100
return