Skip to content

Custom conditions

Custom conditions are user-defined conditions.

A custom condition will impact the atomic evaluation of each conditions (i.e., condition ids).

Vocabulary

To be more precise, a condition expression is something like:

1
CONDITION_1 and CONDITION_2

In that example, the condition expression is made of 2 conditions whose condition ids are:

  • CONDITION_1
  • CONDITION_2

With the built-in condition (also named standard condition), condition ids map to validation functions and condition parameters but we can change that with a brand new custom condition.

A custom condition example:

1
my_condition: NAME_JOHN and AGE_42

Remember

condition ids have to be in CAPITAL LETTERS.

Imagine you want it to be interpreted as (pseudo-code):

1
2
3
if input.name == "john" and input.age == "42":
    # Do something
    ...

With the custom conditions it's quite simple to implement.

Why use a custom condition?

The main goal is to simplify handling of recurrent conditions (e.i., "recurrent" meaning very similar conditions).

Class implementation

First, create a class inheriting from BaseCondtion and implement the verify() method as you want/need:

from typing import Any

from arta.condition import BaseCondition
from arta.utils import ParsingErrorStrategy


class MyCondition(BaseCondition):
    def verify(
        self,
        input_data: dict[str, Any],
        parsing_error_strategy: ParsingErrorStrategy,
        **kwargs: Any
    ) -> bool:

        field, value = tuple(self.condition_id.split("_"))

        return input_data[field.lower()] == value.lower()

self.condition_id

self.condition_id will be NAME_JOHN for the first condition and AGE_42 for the second.

Good to know

The parsing_error_strategy can be used by the developer to adapt exception handling behavior. Possible values:

1
2
3
ParsingErrorStrategy.RAISE
ParsingErrorStrategy.IGNORE
ParsingErrorStrategy.DEFAULT_VALUE

Configuration

Last thing to do is to add your new custom condition in the configuration:

---
rules:
  default_rule_set:
    check_admission:
      ADMITTED_RULE:
        condition: HAS_SCHOOL_AUTHORIZED_POWER
        my_condition: NAME_JOHN and AGE_42  # 
        action: set_admission
        action_parameters:
          value: true
      DEFAULT_RULE:
        condition: null
        action: set_admission
        action_parameters:
          value: false

conditions:
  HAS_SCHOOL_AUTHORIZED_POWER:
    description: "Does applicant have a school authorized power?"
    validation_function: has_authorized_super_power
    condition_parameters:
      power: input.super_power

conditions_source_modules:
  - my_folder.conditions
actions_source_modules: 
  - my_folder.actions

custom_classes_source_modules:
  - dir.to.my_module  # 
condition_factory_mapping:
  my_condition: MyCondition # 

Class diagram

It is based on the following strategy pattern:

Good to know

The class StandardCondition is the built-in implementation of a condition.