Skip to content

Transmutators

Transmutators are similar to CKAN validators. They accept the field and modify it. But unlike validators, transmutators work with field and have access to the whole schema definition.

Usually, transmutator is defined as a function with a single argument. This argument always receives the instance of validated field. It's a dataclass with

  • field_name: the name of processed field
  • value: current value of the field
  • type: the name of the type that contains field definition
  • data: the whole data dictionary that is currently transmuted

To apply transmutator, add its name to the validators attribute of the field definition in transmutation schema:

{
    ...,
    "fields": {
        "my_field": {
            "validators": ["my_transmutator"]
        }
    }
}

When you need to pass additional arguments to transmutator, use the list of name and additional parameters instead of string with name:

{
    ...,
    "fields": {
        "my_field": {
            "validators": [
                "simple_transmutator",
                ["complex_transmutator", 42, "hello_world"]
            ]
        }
    }
}

In the last example, first transmutator will be called as simple_transmutator(field), while second one as complex_transmutator(field, 42, "hello_world")

To pass into transmutator the value of the current field, pass "$self" as an argument. In the similar manner, "$field_name" sends value of the field_name into transmutator:

{
    ...,
    "fields": {
        "my_field": {
            "validators": [
                ["complex_transmutator", "$self", "$other_field", 0]
            ]
        },
        "other_field": {"default": 42}
    }
}

In this case, transmutator will be called as complex_transmutator(field, <VALUE OF CURRENT FIELD>, <VALUE OF other_field>, 0).

Transmutator modifies field in place and returns the whole field when job is done.

ckanext-transmute contains a number of transmutators that can be used without additional configuration. And if you need more, you can define a custom transmutator with the ITransmute interface.

tsm_concat(field, *strings)

Concatenate strings to build a new one.

Example

Greet the value in form Hello VALUE!.

{"validators": [
    ["tsm_concat", "Hello ", "$self", "!"]
]}
PARAMETER DESCRIPTION
field

Field object

TYPE: Field

strings

strings to concat with

TYPE: Any DEFAULT: ()

RETURNS DESCRIPTION
Field

the same Field with new value

TYPE: Field

tsm_get_nested(field, *path)

Fetches a nested value from a field.

Example

Assuming field.value contains {"a": {"b": [1, 2, 3]}}, extract element with key a, from it take element with key b, than get the element with index 1. In the end, value is replaced by 2.

{"validators": [
    ["tsm_get_nested", "a", "b", "1"]
]}
PARAMETER DESCRIPTION
field

Field object

TYPE: Field

path

Iterable with path segments

TYPE: str DEFAULT: ()

RAISES DESCRIPTION
Invalid

raises if path doesn't exist

RETURNS DESCRIPTION
Field

the same Field with new value

TYPE: Field

tsm_isodate(field)

Validates datetime string Mutates an iso-like string to datetime object.

Example

Transform "2022-01-01" into datetime(year=2022, month=1, day=1).

{"validators": ["tsm_isodate"]}

PARAMETER DESCRIPTION
field

Field object

TYPE: Field

RAISES DESCRIPTION
Invalid

raises if date format is incorrect

RETURNS DESCRIPTION
Field

the same Field with casted value

TYPE: Field

tsm_list_mapper(field, mapping, remove=False)

Maps values within a list to corresponding values from the provided dictionary.

Example

Replace ["Finn", "Jake"] with ["human", "dog"].

{"validators": [
    ["tsm_list_mapper", {"Finn": "human", "Jake": "dog"}]
]}
PARAMETER DESCRIPTION
field

Field object

TYPE: Field

mapping

A dictionary representing the mapping of values.

TYPE: dict[Any, Any]

remove

If set to True, removes values from the list if they don't have a corresponding mapping. Defaults to False.

TYPE: bool DEFAULT: False

tsm_map_value(field, test_value, if_same, if_different=SENTINEL)

Replace special value with other value.

Example

Replace me with COOL USER, and any other value with user.

{"validators": [
    ["tsm_map_value", "me", "COOL USER", "user"]
]}
PARAMETER DESCRIPTION
field

Field object

TYPE: Field

test_value

value that will be compared to field.value

TYPE: Any

if_same

value to use if test_value matches the field.value

TYPE: Any

if_different

value to use if test_value does not matche the field.value. Leave empty to keep original value of the field.

TYPE: Any DEFAULT: SENTINEL

tsm_mapper(field, mapping, default=None)

Replace a value with a different value.

The initial value must serve as a key within a mapping dictionary, while the dict value will represent the updated value.

Example

Replace Finn with human, and Jake with dog.

{"validators": [
    ["tsm_mapper", {"Finn": "human", "Jake": "dog"}]
]}
PARAMETER DESCRIPTION
field

Field object

TYPE: Field

mapping

A dictionary representing the mapping of values.

TYPE: dict[Any, Any]

default

The default value to be used when the key is not found. If the default value is not provided, the current value will be used as it.

TYPE: Any DEFAULT: None

RETURNS DESCRIPTION
Field

the same Field with new value

TYPE: Field

tsm_name_validator(field)

Wrapper over CKAN default name_validator validator.

Example

Raise an error for NOT A VALID NAME, but accept not-a-valid-name.

{"validators": ["tsm_name_validator"]}

PARAMETER DESCRIPTION
field

Field object

TYPE: Field

RAISES DESCRIPTION
Invalid

if value is not a valid name

RETURNS DESCRIPTION
Field

the same Field object if it's valid

TYPE: Field

tsm_stop_on_empty(field)

Stop transmutation if field is empty.

Example

Accept the current value and do not call the rest of transmutators if value is represented by falsy object(0, null, empty string, empty list, etc.)

{"validators": [
    "tsm_stop_on_empty",
    "i_am_called_with_nonempty_values_only"
]}

{"validators": [
    "tsm_to_string",
    "tsm_stop_on_empty",
    "only_nonempty_strings_come_here"
]}
PARAMETER DESCRIPTION
field

Field object

TYPE: Field

RETURNS DESCRIPTION
Field

the same Field

TYPE: Field

tsm_string_only(field)

Validates if field.value is string.

Example

Raise an error for 1 but accept "1".

{"validators": ["tsm_string_only"]}

PARAMETER DESCRIPTION
field

Field object

TYPE: Field

RAISES DESCRIPTION
Invalid

raises is the field.value is not string

RETURNS DESCRIPTION
Field

the same Field object if it's valid

TYPE: Field

tsm_to_lowercase(field)

Casts string value to lowercase.

Example

Transform HeLlO to hello.

{"validators": ["tsm_to_lowercase"]}

PARAMETER DESCRIPTION
field

Field object

TYPE: Field

RETURNS DESCRIPTION
Field

Field object with mutated string

TYPE: Field

tsm_to_string(field)

Casts field.value to str.

Example

Transform [1, 2, 3] into string "[1, 2, 3]". Note, that null as missing value will turn into string "None".

{"validators": ["tsm_to_string"]}
PARAMETER DESCRIPTION
field

Field object

TYPE: Field

RETURNS DESCRIPTION
Field

the same Field with new value

TYPE: Field

tsm_to_uppercase(field)

Casts string value to uppercase.

Example

Transform HeLlO to HELLO.

{"validators": ["tsm_to_uppercase"]}

PARAMETER DESCRIPTION
field

Field object

TYPE: Field

RETURNS DESCRIPTION
Field

Field object with mutated string

TYPE: Field

tsm_trim_string(field, max_length)

Trim string lenght.

Example

Keep only first 5 characters in the hello world, turning it into hello.

{"validators": [
    ["tsm_trim_string", 5]
]}
PARAMETER DESCRIPTION
field

Field object

TYPE: Field

max_length

String max length

TYPE: int

RETURNS DESCRIPTION
Field

the same Field object if it's valid

TYPE: Field

tsm_unique_only(field)

Preserve only unique values from list.

Example

Remove duplicates from [1, 1, 2, 1, 2, 2, 1, 3], keeping [1, 2, 3].

{"validators": ["tsm_unique_only"]}
PARAMETER DESCRIPTION
field

Field object

TYPE: Field

RETURNS DESCRIPTION
Field

the same Field with new value

TYPE: Field