Working with placeholders#
This guide provides instructions for working with placeholders in optiSLang.
Overview#
In optiSlang, placeholders are variables that can be assigned to workflow component (node) properties, allowing you to easily update properties in more than one workflow component at a time. You can also use placeholders to directly expose workflow component properties for external modification (for example, by a user of an optiSLang App or the command line interface).
Each placeholder has the following attributes:
ID: A unique identifier for the placeholder
Data Type: Specifies what kind of data the placeholder can hold
User Level: Controls which user roles can modify the placeholder
Description: Optional documentation about the placeholder’s purpose
Depending on the desired use case, placeholders can either store fixed values or be composed out of other placeholders via a macro expression. The respective attributes are:
Value: The current value stored in the placeholder
Range: The range of allowed values
Macro Expression: The macro expression defining the placeholder’s composition. See “Placeholder Macro Language” in the optiSLang documentation for more information.
API capabilities for managing placeholders include:
Creating placeholders with specific data types and user access levels
Assigning values appropriate to their data type
Querying and filtering by ID patterns
Renaming and removing
Assigning to and unassigning from node properties
The API supports both project-level operations (via Project
class) for managing placeholders globally and node-level operations (via Node
class) for creating placeholders from node properties and managing assignments to them.
Creating placeholders#
Placeholders are intended to be values stored separately from the workflow components in the project and then assigned to one or multiple workflow component properties.
Creating placeholders can be achieved by either creating a stand-alone (unassigned) one (via create_placeholder()
) and then assign it to a workflow component property (via assign_placeholder()
) or directly creating the placeholder from a workflow component property (via via create_placeholder_from_property()
).
Variant 1 - Step 1: Create stand-alone placeholder#
from ansys.optislang.core import Optislang
from ansys.optislang.core.placeholder_types import PlaceholderType, UserLevel
# Connect to optiSLang
osl = Optislang()
# Create a real number placeholder for thickness
thickness_id = osl.project.create_placeholder(
value=5.0,
placeholder_id="thickness",
type_=PlaceholderType.REAL,
user_level=UserLevel.COMPUTATION_ENGINEER,
description="Plate thickness in mm",
)
# Create a string placeholder for material name
material_id = osl.project.create_placeholder(
value="Steel",
placeholder_id="material_name",
type_=PlaceholderType.STRING,
user_level=UserLevel.FLOW_ENGINEER,
description="Material name",
)
# Create an integer placeholder for maximum number of parallel executions
global_max_parallel_id = osl.project.create_placeholder(
value=8,
placeholder_id="global_max_parallel",
type_=PlaceholderType.UINT,
user_level=UserLevel.FLOW_ENGINEER,
description="Maximum number of parallel executions",
)
Variant 1 - Step 2: Assigning existing placeholders#
Placeholders are type-specific. A placeholder can be assigned to a project property only if they share the same data type.
from ansys.optislang.core import node_types
# Get a node reference
root_system = osl.project.root_system
mop_solver_node = root_system.create_node(
type_=node_types.Mopsolver, name="MOPSolver Node"
)
# Assign the placeholder to a node property
mop_solver_node.assign_placeholder(
property_name="MaxParallel", placeholder_id="global_max_parallel"
)
Variant 2: Creating placeholders directly from node properties#
from ansys.optislang.core import node_types
# Get a node reference
root_system = osl.project.root_system
mop_solver_node = root_system.create_node(
type_=node_types.Mopsolver, name="MOPSolver Node"
)
# Create a placeholder from a node property
placeholder_id = mop_solver_node.create_placeholder_from_property(
property_name="MaxParallel", placeholder_id="max_parallel"
)
print(f"Created placeholder: {placeholder_id}")
# Create placeholder with auto-generated ID
auto_id = mop_solver_node.create_placeholder_from_property(property_name="RetryCount")
print(f"Auto-generated placeholder ID: {auto_id}")
Creating placeholders with macro expressions#
optiSLang allows you to define macro expressions. Macro expressions create placeholder values composed of other user-defined placeholders or predefined constants. By using macro expressions, complex workflow component properties like algorithm systems parametric can be assembled out of separate placeholder values for e.g parameter reference values or ranges. The separate placeholders can then be configured to be accessible externally. The macro language slightly differs between the types, but all types share the same rules for placeholder substitution, text concatenation, and literal escaping. Please refer to the optiSLang documentation on more information on the macro language syntax.
# Get a node reference
root_system = osl.project.root_system
mop_solver_node = root_system.create_node(
type_=node_types.Mopsolver, name="MOPSolver Node"
)
# Create a placeholder as an expression from a node property. The placeholder will be assigned to the node property. The property value will be used as expression value by default.
placeholder_id = mop_solver_node.create_placeholder_from_property(
property_name="MaxParallel", create_as_expression=True
)
print(f"Created expression placeholder: {placeholder_id}")
# You can also directly specify the expression.
placeholder_id_2 = mop_solver_node.create_placeholder_from_property(
property_name="MaxParallel", expression="global_max_parallel/2"
)
print(f"Created expression placeholder: {placeholder_id_2}")
Unassigning placeholders from nodes#
Placeholders can be unassigned from node properties when their parametrization is no longer needed by using unassign_placeholder()
.
# Unassign a placeholder from a node property
try:
mop_solver_node.unassign_placeholder(property_name="MaxParallel")
print("✓ Placeholder unassigned from MaxParallel property")
except Exception as e:
print(f"✗ Failed to unassign placeholder: {e}")
Querying placeholders#
You can query existing placeholders to retrieve information about their configuration by using get_placeholder_ids()
and get_placeholder()
.
Getting all placeholder IDs#
# Get all placeholder IDs in the project
placeholder_ids = osl.project.get_placeholder_ids()
print(f"Found {len(placeholder_ids)} placeholders:")
for placeholder_id in placeholder_ids:
print(f" - {placeholder_id}")
Getting placeholder information#
# Get detailed information about a specific placeholder
placeholder_info = osl.project.get_placeholder("thickness")
print(f"Placeholder ID: {placeholder_info.placeholder_id}")
print(f"Type: {placeholder_info.type}")
print(f"User Level: {placeholder_info.user_level}")
print(f"Description: {placeholder_info.description}")
print(f"Current Value: {placeholder_info.value}")
# Get information about all placeholders
placeholder_ids = osl.project.get_placeholder_ids()
for placeholder_id in placeholder_ids:
info = osl.project.get_placeholder(placeholder_id)
print(f"ID: {info.placeholder_id}, Type: {info.type}, Value: {info.value}")
Editing placeholder configuration and setting values#
After creating placeholders, you can modify their configuration by using create_placeholder()
again and specifying the overwrite
argument.
As a convenience you can use set_placeholder_value()
to set their values specifically.
# Modify one or multiple configuration entries of a placeholder
osl.project.create_placeholder(
placeholder_id="global_max_parallel",
value=18,
description="Adapted description for maximum number of parallel executions",
overwrite=True,
)
# Set a placeholder value specifically
osl.project.set_placeholder_value("thickness", 7.5)
Validating placeholder updates#
# Set a value and verify it was updated
new_value = 8.5
osl.project.set_placeholder_value("thickness", new_value)
# Verify the update
placeholder_info = osl.project.get_placeholder("thickness")
current_value = placeholder_info.value
if current_value == new_value:
print(f"✓ Successfully updated thickness to {new_value}")
else:
print(f"✗ Update failed. Expected {new_value}, got {current_value}")
Renaming placeholders#
Placeholders can be renamed while preserving their values and assignments by using rename_placeholder()
.
# Rename a placeholder
old_id = "thickness"
new_id = "plate_thickness"
try:
osl.project.rename_placeholder(old_id, new_id)
print(f"✓ Renamed '{old_id}' to '{new_id}'")
except Exception as e:
print(f"Failed to rename placeholder: {e}")
Removing placeholders#
Placeholders can be removed from the project when no longer needed by using remove_placeholder()
.
# Remove a placeholder by ID
try:
osl.project.remove_placeholder("plate_thickness")
print("Placeholder removed successfully")
except Exception as e:
print(f"Failed to remove placeholder: {e}")