Validators
Overview
It can be useful to restrict the set of that values that a parameter node parameter can be set to. These can be done with Validator
annotations.
from typing import Annotated
from slicer.parameterNodeWrapper import parameterNodeWrapper, Minimum, Default
@parameterNodeWrapper
class CustomParameterNode:
numIterations: Annotated[int, Minimum(0)] = 500
# To have a list where the values in the list need to be validated
chosenFeatures: list[Annotated[str, Choice(["feat1", "feat2", "feat3"])]]
This will cause a ValueError
to be raised if someone tried setting numIterations
to a negative value.
Multiple validators can be placed in the Annotated
block and they will be run in the order they were placed.
Built-in validators
The list of built-in validators is as follows:
Class name | Description |
---|---|
NotNone() |
Ensures the value is not None . |
IsInstance(classtype) /IsInstance((class1type, class2type)) |
Ensures the value is an instance of particular type or set of types. |
Minimum(value) |
Ensures the value is greater than or equal to the given value. |
Maximum(value) |
Ensures the value is less than or equal to the given value. |
WithinRange(minimum, maximum) |
Ensures the value is within the range given by minimum and maximum, inclusive. |
Choice(validChoices) |
Ensures the value is contained in the given list of valid choices. validChoices can be any iterable. |
Exclude(invalidChoices) |
Ensures the value is not contained in the given list of invalid choices. invalidChoices can be any iterable. |
Some built-in types have the following validators applied to them by default:
Type | Default validators |
---|---|
int , str , bool , any of the pathlib path types |
NotNone() , IsInstance(<type>) |
float |
NotNone() , IsInstance((float, int)) (this allows implicit conversion from int) |
vtkMRMLModelNode (and subclasses) |
IsInstance(<type>) |
Custom Validators
Custom validators can easily be created and used with the parameterNodeWrapper
.
import re
from typing import Annotated
from slicer.parameterNodeWrapper import parameterNodeWrapper, Validator
# Custom validators must derive from the Validator class.
class MatchesRegex(Validator):
def __init__(self, regex):
self.regex = regex
# Custom validators must implement a validate function that raises an Exception
# if the given value is invalid.
def validate(self, value):
if re.match(self.regex, value) is None:
raise ValueError("Did not match regex")
@parameterNodeWrapper
class CustomParameterNode:
value: Annotated[str, MatchesRegex("[abc]+")] = "abcba"
param = CustomParameterNode(slicer.mrmlScene.AddNewNodeByClass('vtkMRMLScriptedModuleNode'))
param.value = "abcabc" # ok
param.value = "d" # ValueError raised