Expressions
Expressions are Python code snippets that compute dynamic values, which can be referenced in operation steps using template syntax.
Basic Usage
Define expressions that evaluate to values:
dyngle:
operations:
greet:
expressions:
greeting: "'Hello ' + name + '!'"
steps:
- echo "{{greeting}}"
Run it:
echo "name: Alice" | dyngle run greet
Output:
Hello Alice!
Expression Scopes
Global Expressions
Defined under dyngle: and available to all operations:
dyngle:
expressions:
timestamp: "datetime.now()"
author: "'Francis Potter'"
operations:
log:
- echo "[{{timestamp}}] Log by {{author}}"
Local Expressions
Defined within a specific operation:
dyngle:
operations:
say-hello:
expressions:
count: len(name)
steps:
- echo "Hello {{name}}! Your name has {{count}} characters."
Local expressions override global expressions with the same name.
Expression Context
Expressions evaluate in a context that includes:
- Data values - Referenced directly as Python variables
- Built-in functions -
len(),str(), etc. - Standard library modules -
datetime,math, etc. - Special functions -
get(),format(),dtformat(),Path() - Command arguments - Available as the
argsarray
Referencing Data
Data values can be referenced directly:
dyngle:
operations:
greet:
expressions:
message: "'Hello ' + name"
steps:
- echo "{{message}}"
Hyphenated Names
YAML keys can contain hyphens. To reference them in expressions:
Option 1: Replace hyphens with underscores:
dyngle:
operations:
greet:
expressions:
message: "'Hello ' + first_name" # References 'first-name'
steps:
- echo "{{message}}"
Option 2: Use the get() function:
dyngle:
operations:
greet:
expressions:
message: "'Hello ' + get('first-name')"
steps:
- echo "{{message}}"
Special Functions
get()
Retrieve values from the data context:
dyngle:
expressions:
full-greeting: "'Hello ' + get('first-name') + ' ' + get('last-name')"
The get() function can also reference other expressions:
dyngle:
expressions:
greeting: "'Hello'"
full-greeting: "get('greeting') + ' ' + name"
format()
Render a template string using the current data context:
dyngle:
values:
first-name: Alice
last-name: Smith
operations:
greet:
expressions:
full-greeting: format('Hello, {{first-name}} {{last-name}}!')
steps:
- echo "{{full-greeting}}"
The format() function supports all template syntax, including nested properties:
dyngle:
operations:
weather-report:
expressions:
report: format('Temperature in {{location.city}} is {{weather.temperature}} degrees')
steps:
- echo "{{report}}"
See Data and Templates for more about template syntax.
dtformat()
Format datetime objects as strings:
dyngle:
expressions:
now: "datetime.now()"
timestamp: "dtformat(get('now'), '%Y-%m-%d %H:%M:%S')"
operations:
log:
- echo "[{{timestamp}}] Event occurred"
Path()
Create path objects (restricted to current working directory):
dyngle:
expressions:
config-file: "Path('.dyngle.yml')"
exists: "get('config-file').exists()"
args
Access command-line arguments passed to the operation:
dyngle:
operations:
greet-arg:
expressions:
name: "args[0] if args else 'World'"
steps:
- echo "Hello {{name}}!"
Run it:
dyngle run greet-arg Alice
YAML Structure Syntax
Instead of string-based Python expressions, you can use native YAML structures:
Dictionaries
dyngle:
operations:
api-call:
expressions:
request-body:
user: get('username')
email: get('email')
timestamp: "datetime.now()"
steps:
- echo "Request: {{request-body}}"
Arrays
dyngle:
expressions:
coordinates:
- get('latitude')
- get('longitude')
- get('altitude')
Nested Structures
dyngle:
expressions:
config:
server:
host: format("{{server-host}}")
port: "int(get('server-port'))"
database:
name: format("{{db-name}}")
connection:
- format("{{db-host}}")
- "int(get('db-port'))"
Important Notes:
- Each string in a YAML structure is evaluated as a Python expression
- Numbers, booleans, and None pass through unchanged
- String literals require Python string syntax:
"'literal string'" - Access nested properties in templates using dot notation:
{{config.server.host}} - Access array elements in expressions using Python brackets:
get('coordinates')[0]
Available Python Features
Expressions support:
Built-in types and functions:
str(),int(),float(),bool(),len(), etc.
Standard library modules:
datetime- Date and time operationsmath- Mathematical functionsPath()- File path operations (restricted to current directory)
Data structures:
- Lists, dictionaries, tuples
- List comprehensions
- Dictionary comprehensions
Operators:
- Arithmetic:
+,-,*,/,//,%,** - Comparison:
==,!=,<,>,<=,>= - Logical:
and,or,not - String: concatenation, formatting
Control flow (in comprehensions):
if/elsein expressionsforloops in comprehensions
Expression Examples
String manipulation
dyngle:
expressions:
uppercase-name: "name.upper()"
initials: "'.'.join([word[0] for word in name.split()])"
Mathematical operations
dyngle:
expressions:
circle-area: "math.pi * radius ** 2"
rounded: "round(get('circle-area'), 2)"
Date and time
dyngle:
expressions:
now: "datetime.now()"
today: "get('now').date()"
formatted-date: "dtformat(get('now'), '%B %d, %Y')"
List operations
dyngle:
values:
numbers: [1, 2, 3, 4, 5]
expressions:
doubled: "[n * 2 for n in get('numbers')]"
sum-numbers: "sum(get('numbers'))"
max-number: "max(get('numbers'))"
Conditional logic
dyngle:
expressions:
environment: "get('env') if get('env') else 'development'"
log-level: "'DEBUG' if get('environment') == 'development' else 'INFO'"