Module: Decorators
Important
App decorators have been updated with breaking changes in TcEx 2.0.
The ThreatConnect TcEx App Framework provides multiple Python decorators to help in setup of task that are common in Apps. Using multiple decorators on a single method is common.
Fail on Output
The FailOnOutput()
decorator is useful in decorating methods that should have a valid and/or specific output. The decorator can be enabled/disable directly by the App developer or based on a user input (e.g., Boolean input value in install.json).
The following example adds the FailOnOutput
decorator to a method that takes a single IP Address input. If the fail_on_false
input is enabled and an invalid IP Address is provided the App will exit with the provided fail_msg. This decorator provides a decent amount of flexibility, provides consistent functionality, and reduces redundant code in the App.
1import ipaddress
2from tcex import FailOnOutput
3
4@FailOnOutput(
5 fail_enabled='fail_on_false', # references input value fail_on_false
6 fail_msg='App failed due to invalid ip address', # exit message
7 fail_on=[False], # invalid return values
8 write_output=True, # regardless of pass/fail write output variables
9)
10def is_ip_address(self, ip_address):
11 """Return True if input is a valid ipv4 address."""
12 try:
13 ipaddress.ip_address('192.168.0.1')
14 except ValueError:
15 return False
16 return True
Iterate On Arg
The IterateOnArg()
decorator is useful in decorating methods that process a single and array input. This decorator can be very useful in action based Apps. This decorator accepts validators and transforms in the same manner as ReadArg()
, please see that section for details.
The following example adds the IterateOnArg
decorator to a method that takes a String or StringArray input and returns the value capitalized. The decorator will call the method one time for each item in the input array (a single String input value would be automatically converted to an StringArray). If the fail_enabled
input is enabled and any supplied validators fail, the App would then exit using the fail_msg string provided. This decorator provides a decent amount of flexibility, provides consistent functionality, and reduces redundant code in the App.
1from tcex import IterateOn
2
3@IterateOnArg(
4 arg='colors',
5 default=None,
6 fail_enabled='fail_on_error,
7 fail_msg='Failed to capitalize string input.',
8 fail_on=['None' ''],
9)
10def capitalize(self, colors):
11 """Return capitalized string."""
12 return colors.capitalize()
On Exception
The OnException()
decorator is useful in decorating methods that may have an exception that needs to be handled consistently.
The following example adds the OnException
decorator to a method that processes an input. The decorator will catch any Exception and write an exit message. If the fail_on_error
input is enabled and an exception is caught, the App would then exit using the exit_msg string provided. This decorator provides a decent amount of flexibility, provides consistent functionality, and reduces redundant code in the App.
1from tcex import OnException
2
3@OnException(
4 exit_msg='Failed to capitalize input.',
5 exit_enabled='fail_on_error',
6 write_output=False
7)
8def capitalize(self, colors):
9 """Return capitalized string."""
10 return colors.capitalize()
On Success
The OnSuccess()
decorator is useful in decorating methods with a predefined exit message on successfully execution.
The following example adds the OnSuccess
decorator to a method that processes an input. The decorator set the exit message of the App when the method successfully completes.
1from tcex import OnSuccess
2
3@OnSuccess(exit_msg='Successfully capitalized input.')
4def capitalize(self, colors):
5 """Return capitalized string."""
6 return colors.capitalize()
Output
The Output()
decorator is useful in decorating methods that provide output that will be used during the write_output()
method.
The following example adds the Output
decorator to a method that processes an input. The decorator will add the output of the method to the attribute provided to the decorator. This method is helpful when using the IterateOn()
decorator. For each execution of the method the return data is appended/extended to the provided attribute. This decorator provides a decent amount of flexibility, provides consistent functionality, and reduces redundant code in the App.
1from tcex import Output
2
3def __init__(self):
4 """Initialize class properties."""
5 self.output_data = None
6
7@Output(attribute='output_data', overwrite=False)
8def capitalize(self, colors):
9 """Return capitalized string."""
10 return colors.capitalize()
Read Arg
The ReadArg()
decorator is useful in decorating methods that use a user input.
The following example adds the ReadArg
decorator to a method that takes a String. The decorator will call the method passing the value of the append_chars input. If the fail_on_error
input is enabled and the input matches a value in the fail_on array, the App would then exit using the fail_msg string provided. This decorator provides a decent amount of flexibility, provides consistent functionality, and reduces redundant code in the App.
1from tcex.decorators import ReadArg
2
3@ReadArg(
4 arg='append_chars',
5 fail_enabled='fail_on_error,
6 fail_on=['None' ''],
7)
8def append(self, string, append_chars):
9 """Return string with appended characters."""
10 return f'{string}{append_chars}'
The ReadArg()
decorator includes several built-in transforms that modify the value of the input and validators that perform checks on the input but do not change its value.
The following built-in transforms are available:
to_bool
to_float
to_int
The following built-in validators are available:
equals
in_range
greater_than
greater_than_or_equal
less_than
less_than_or_equal
not_in (this is equivalent to fail_on)
Transforms are run, in the order they are passed, before validators, which are also run in the order they are passed.
1from tcex.decorators import ReadArg
2
3@ReadArg(
4 arg='confidence',
5 fail_enabled='fail_on_error,
6 fail_on=['None' ''],
7 to_int=True,
8 in_range={'min': 0, 'max': 100}
9)
10def append(self, confidence):
11 """Return string with appended characters."""
12 return f'{confidence}'
Custom validators and transforms can be defined using the validators
and transforms
arguments. Both validators and transforms are callables that accept the input value and input name and raise a tcex.validators.ValidationError
if the input is invalid. Validators do not return a value, but transforms should return a new value for the input.
1from tcex.decorators import ReadArg
2from tcex.validators import ValidationError
3
4def to_email(value, arg_name):
5 """This is a transform that takes a name and returns the associated email address"""
6 name_to_email = {
7 'Bob': '[email protected]',
8 'Sally': '[email protected]'
9 }
10
11 if value in name_to_email:
12 return name_to_email.get(value)
13
14 raise ValidationError(f'no email found for {value}.')
15
16def is_valid_label(value, arg_name):
17 valid_labels = ['High', 'Medium', 'Low']
18 if value not in valid_labels:
19 raise ValidationError(f'{arg_name} must be High, Medium, or Low')
20
21@ReadArg(
22 arg='email_to',
23 transforms=[to_email]
24)
25@ReadArg(
26 arg='label',
27 validators=[is_valid_label]
28)
29def append(self, email_to, label):
30 """Return string with appended characters."""
31 return f'{email_to} - {label}'