Code blocks

Code blocks allow you to add custom Python code directly within your agentic workflow. The code block node receives data from upstream node, processes it by using the logic that you define, and passes the transformed output to the downstream node. You can use a code block to process data transformations, implement custom logic or format messages before they continue to the next step in the agentic workflow.

When the agentic workflow reaches a code block node, it runs the Python code that you defined and transforms the data. The node acts as a programmable decision or transformation point in your agentic workflow, giving you greater flexibility and control. If you want to use a larger Python code block, consider using a tool.

Python libraries

Within a code block, you can read variables from different parts of the agentic workflow, apply custom logic, and define output variables for use by subsequent nodes. The Python environment includes commonly used standard libraries, including the following modules:

  • array
  • calendar
  • collections
  • datetime
  • enum
  • json
  • math
  • random
  • re
  • string
  • time
  • yaml
  • zoneinfo

Support for Python functions

The following list describes the functions that are not supported and recommended alternatives.

  • The eval() function is not supported. Use (my_str == "True") instead of eval(my_str), where my_str is either "True" or "False".
  • For yaml module only safe_load(), safe_load_all(), safe dump() and safe_dump_all() API functions are supported.
  • For string module string.Formatter is not supported. Use string.safe_format() instead of string.Formatter.format().
  • For str function str.format() is not supported. Any xxx.format() or xxx.format_map() API functions are not supported.
  • Some built-in Python functions are not supported, including import, class, and type(). To check types, use safe_type() instead of type().
Note:
  • The list of available Python modules is fixed and cannot be changed or extended.
  • Some libraries in the Python modules may not be available.
  • Variables can be referenced by using either ["varname"] or .varname. Using ["varname"] allows for the use of spaces and commas.

Python dictionary objects

Agentic workflow builder uses Python programming practices, therefore flow, self, and parent are treated as Python dictionaries. If you get an exception while reading from or assigning to a self-object, for example: self["input"]["customer"]["discount_rate"], it is likely because one of the containing objects (like "customer") does not exist yet. In that case, you need to first initialize the containing objects.

When a code block runs, it uses Python dictionary objects to represent the inputs and outputs. You can use expression syntax to reference or set these values as needed. For more information about the syntax, see the Flow expressions section of the IBM wastonsx Orchestrate ADK.

Here is an example agentic workflow dictionary:

# flow represents the inputs and outputs of the outermost flow
flow = {
  "input": {
    "birthday": "1-10-2000",
    "first_name": "John",
    "last_name": "Doe",
    "address": {
      "street": "123 ABC Street",
      "city": "NY",
      "state": "NY",
      "country": "USA"
    },
    "customer_status": "Bronze"
  },
  "output": {
    "current_date": "<current date>",
    "current_datetime": "<current datetime>",
    "age": <number>,
    "address": <str>
  }
}

# self represents the inputs and outputs of the current node
self = {
  "input": {
    "customer_status": "Bronze",
    "price": 1000
  },
  "output": {
    "discount_rate": <number>
  }
}

Data types

The following table lists the data types that are supported in agentic workflows, along with their equivalent Python and JSON types used in expressions and code blocks.

Flow data type Python data type JSON data type
String str string
Integer int integer
Number float number
Boolean bool boolean
Date str string
Object dict object

Note:

  • To define an object data type in agentic workflows, you must adhere to the JSON schema standard. For more information, see the JSON Schema documentation.

  • In Python, dates are strings that use the ISO 8601 date format. JSON dates are strings with a “date” format, which uses the ISO 8601 date format, for example:

"startDate": {
 "type": "string",
 "description": "Employee's start date",
 "format": "date"
}

Data type conversion

Data type conversions allow transforming a value from one format to another. The following code blocks provide Python expression examples of different types of data conversion.

Examples

String conversion


A code block that converts a string into an integer.
my_str = str("10")

my_int = int(my_str)

test_results += "my_str: " + my_str + " converted to my_int: " + str(my_int) + "\n"



A code block that converts a string into a number.
my_str = str("1.5")

my_num = float(my_str)

test_results += "my_str: " + my_str + " converted to my_num: " + str(my_num) + "\n"



A code block that converts a string into a boolean.
my_str = str("False")
my_bool = (my_str == "True")
test_results += "my_str: " + my_str + " converted to my_bool: " + str(my_bool) + "\n"
my_str = str("True")
my_bool = (my_str == "True")
test_results += "my_str: " + my_str + " converted to my_bool: " + str(my_bool) + "\n"


A code block that converts a string into a date.
my_str = str("2021-01-01")

my_date_str = my_str

test_results += "my_str: " + my_str + " converted to my_date_str: " + my_date_str + "\n"

Note: Python dates are strings that conform to the ISO 8601 date format: "%Y-%m-%d"



A code block that converts a string into a date by using datetime package.
my_date_date = datetime.datetime.strptime(my_date_str, "%Y-%m-%d").date()

my_date_date = my_date_date + datetime.timedelta(days=1)

my_date_str = my_date_date.strftime("%Y-%m-%d")

test_results += "added one day to my_date_str: " + my_date_str + "\n"



Integer conversion


A code block that converts an integer into a string.
my_int = int(10)
my_str = str(my_int)
test_results += "my_int: " + str(my_int) + " converted to my_str: " + my_str + "\n"


A code block that converts an integer into a number.
my_int = int(10)
my_num = float(my_int)
test_results += "my_int: " + str(my_int) + " converted to my_num: " + str(my_num) + "\n"


A code block that converts an integer into a boolean.
my_int = int(0)
my_bool = bool(my_int)
test_results += "my_int: " + str(my_int) + " converted to my_bool: " + str(my_bool) + "\n"
my_int = int(1)
my_bool = bool(my_int)
test_results += "my_int: " + str(my_int) + " converted to my_bool: " + str(my_bool) + "\n"

Note: In this code block example, 0 is converted to False, and 1 is converted to True.



A code block that converts an integer into a date.
my_int = int(739470)
my_date_date = datetime.date.fromordinal(my_int)
my_date_str_isoformat = my_date_date.isoformat()
test_results += "my_int: " + str(my_int) + " converted to my_date_date: " + my_date_str_isoformat + "\n"


Number conversion


A code block that converts a number into a string.
my_num = float(1.5)
my_str = str(my_num)
test_results += "my_num: " + str(my_num) + " converted to my_str: " + my_str + "\n"


A code block that converts a number into an integer.
my_num = float(1.5)
my_int = int(my_num)
test_results += "my_num: " + str(my_num) + " converted to my_int: " + str(my_int) + "\n"
my_int = math.ceil(my_num)
test_results += "my_num: " + str(my_num) + " converted to my_int using math.ceil(): " + str(my_int) + "\n"
my_int = math.floor(my_num)
test_results += "my_num: " + str(my_num) + " converted to my_int using math.floor(): " + str(my_int) + "\n"

Note: Use math.ceil() to round up and math.floor() to round down.



A code block that converts a number into a boolean.
my_num = float(0)
my_bool = bool(my_num)
test_results += "my_num: " + str(my_num) + " converted to my_bool: " + str(my_bool) + "\n"
my_num = float(1)
my_bool = bool(my_num)
test_results += "my_num: " + str(my_num) + " converted to my_bool: " + str(my_bool) + "\n"

Note: In this code block example, 0 is converted to False, and 1 is converted to True.



A code block that converts a number into a date.
my_num = float(739470)
my_date_date = datetime.date.fromordinal(int(my_num))
my_date_str_isoformat = my_date_date.isoformat()
test_results += "my_num: " + str(my_num) + " converted to my_date_date: " + my_date_str_isoformat + "\n"


Boolean conversion


A code block that converts a boolean into a string.
my_bool = bool(True)
my_str = str(my_bool)
test_results += "my_bool: " + str(my_bool) + " converted to my_str: " + my_str + "\n"
my_bool = bool(False)
my_str = str(my_bool)
test_results += "my_bool: " + str(my_bool) + " converted to my_str: " + my_str + "\n"


A code block that converts a boolean into an integer.
my_bool = bool(True)
my_int = int(my_bool)
test_results += "my_bool: " + str(my_bool) + " converted to my_int: " + str(my_int) + "\n"
my_bool = bool(False)
my_int = int(my_bool)
test_results += "my_bool: " + str(my_bool) + " converted to my_int: " + str(my_int) + "\n"


A code block that converts a boolean into a number.
my_bool = bool(True)
my_num = float(my_bool)
test_results += "my_bool: " + str(my_bool) + " converted to my_num: " + str(my_num) + "\n"
my_bool = bool(False)
my_num = float(my_bool)
test_results += "my_bool: " + str(my_bool) + " converted to my_num: " + str(my_num) + "\n"


Date conversions


A code block that converts a date into a string.
my_date_date = datetime.date.today()
my_date_str_isoformat = my_date_date.isoformat()
my_date_str = my_date_date.strftime("%a %d %B %Y")
test_results += "my_date_date: " + my_date_str_isoformat + " converted to my_date_str: " + my_date_str + "\n"

Note: For more information about date format codes, see Python strftime and strptime format codes.



A code block that converts a date into an integer.
my_date_date = datetime.date.today()
my_date_str_isoformat = my_date_date.isoformat()
my_int = int(my_date_date.toordinal())
test_results += "my_date_date: " + my_date_str_isoformat + " converted to my_int: " + str(my_int) + "\n"


A code block that converts a date into a number.
my_date_date = datetime.date.today()
my_date_str_isoformat = my_date_date.isoformat()
my_num = float(my_date_date.toordinal())
test_results += "my_date_date: " + my_date_str_isoformat + " converted to my_num: " + str(my_num) + "\n"
self.output.test_results = test_results


Use cases and examples

You can use the code block node to customize how your agentic workflow handles data. It is useful when standard nodes do not meet your specific needs. The following are some common use cases.

Message formatting

You can format or restructure messages as needed, while also moving information to the next node. The following code block example shows a practical application of message formatting.

Examples


A code block that formats address input and displays it as a single string separated by commas.
# Format address
addr = flow["input"]["address"]
formatted_address = f"{addr['street']}, {addr['city']}, {addr['state']}, {addr['country']}"
self["output"]["address"] = formatted_address


Flexible integration

You can place the code block node anywhere in the agentic workflow to integrate with other nodes and tools. The following code block sample shows a practical application of flexible integration.

Examples


A code block that defines a variable that is called todays_date as a Date data type and initializes todays_date and sets the value to the current date.
today = datetime.date.today()

self.output.todays_date = today.isoformat()



A code block that initializes a set of output variables using primitive data types: string, integer, number, and boolean.

The output variables are:

  • name : String
  • age : Integer
  • salary : Number
  • isActive : Boolean

In the code block, each variable is initialized with a sample value.

self.output.name = "John Doe"
self.output.age = 37
self.output.salary = 12345.67
self.output.isActive = True


Custom data transformation

You can write Python code to transform, filter, initialize variables, or enhance existing data as it passes through the agentic workflow. The following code block examples show a practical application of custom data transformation.

Examples


A code block that parses a JSON string containing address fields into a Python dictionary.
address_json = '''

{   "street": "123 ABC Street",   "city": "NY",   "state": "NY",   "country": "USA" }

'''

address = json.loads(address_json)



A code block that assigns the state value from the address dictionary to the input address in the agentic workflow.
This code block runs only if flow["input"]["address"] already exists. If it does not exist, you must create it first.
flow["input"]["address"]["state"] = address["state"]


A code block sets and initializes an output variable called employee as an object data type.
The variable type is defined using a JSON Schema structure.

{
    "id": {
        "type": "integer",
        "description": "Unique identifier for the employee"
    },
    "firstName": {
        "type": "string",
        "description": "Employee's first name"
    },
"lastName": {
    "type": "string",
    "description": "Employee's last name"
},
"email": {
    "type": "string",
    "description": "Employee's email address"
},
"department": {
    "type": "string",
    "description": "Employee's department"
},
"salary": {
    "type": "number",
    "description": "Employee's salary"
},
"isActive": {
    "type": "boolean",
    "description": "Whether the employee is currently active"
},
"startDate": {
    "type": "string",
    "format": "date",
    "description": "Employee's start date"
},
"badges": {
    "type": "array",
    "items": {
        "type": "string"
    },
    "description": "Employee's badges"
},
"address": {
    "type": "object",
    "properties": {
        "street": {
            "type": "string"
        },
        "city": {
            "type": "string"
        },
        "zipCode": {
            "type": "string"
        }
    }
}

} self.output.employee ={ "id": "12345", "firstName": "John", "lastName": "Doe", "email": "john.doe@example.com", "department": "Sales", "salary": 50000, "isActive": True, "startDate": "2021-01-01", "badges": [ "Badge1", "Badge2" ], "address": { "street": "123 Main St", "city": "Anytown", "zipCode": "12345" } }



Business logic implementation

You can apply conditional logic, compute calculations and decisions, or run custom operations as needed in the agentic workflow. The following code block examples show a practical application of business logic implementation.

Examples


A code block that calculates and displays the user's age based on the date of birth input.
# Get today's date
today = datetime.date.today()

# Get the user's birthday from the output of the previous user activity
birthday_str = flow["User activity 1"]["Ask for date of birth"].output.value

# Convert the user's birthday into a date object
birthday = datetime.datetime.strptime(birthday_str, "%Y-%m-%d").date()

# Calculate the user's age
age = today.year - birthday.year - ((today.month, today.day) < (birthday.month, birthday.day))

# Return the user's age
self.output.age = age



A code block that checks the product type and age to determine whether to accept payment.
product = flow.input.product

age = flow.input.age

if product == "Alcohol" and age < 18: self.output.accept_payment = False elif product == "Fireworks" and age < 18: self.output.accept_payment = False else: self.output.accept_payment = True



A code block that displays a discount rate based on input variables price and customer_status.
# Ensure customer_status and price are available

status = flow["input"].get("customer_status") price = flow["input"].get("price", 0)

discount_rate = 0

if status == "Bronze":     if price < 100:         discount_rate = 0     elif price < 500:         discount_rate = 0.01

elif price < 900:         discount_rate = 0.02     else:         discount_rate = 0.03 elif status == "Silver":     if price < 100:         discount_rate = 0.02     elif price < 500:         discount_rate = 0.04     elif price < 900:         discount_rate = 0.05     else:         discount_rate = 0.07 elif status == "Gold":     if price < 100:         discount_rate = 0     elif price < 500:         discount_rate = 0.05     elif price < 900:         discount_rate = 0.07     else:         discount_rate = 0.10

self["output"]["discount_rate"] = discount_rate



A code block that formats the address input into a string by using if-then logic.
# Format address using if-then logic

addr = flow["input"]["address"] formatted_address = addr["street"]

if addr.get("city"): formatted_address += f", {addr['city']}" if addr.get("state"): formatted_address += f", {addr['state']}" if addr.get("country"): formatted_address += f", {addr['country']}"

self["output"]["address"] = formatted_address



A code block that calculates the date three days earlier from the current date, and stores it in the variable thee_days_ago.
today = datetime.date.today()

three_days_ago = today - datetime.timedelta(days=3)

self.output.three_days_ago = three_days_ago.isoformat()