Skip to main content

NoETL DSL Reference

The NoETL Domain-Specific Language (DSL) defines how workflows are structured and executed. This section covers the complete syntax, patterns, and features of the DSL.

Core Specification

  • DSL Specification - Complete reference for playbook syntax, step structure, and workflow patterns

Variables & Data Flow

Control Flow

DSL Overview

Playbook Structure

apiVersion: noetl.io/v2
kind: Playbook
metadata:
name: example_workflow
path: workflows/example
workload:
variable: value
workbook:
- name: reusable_task
tool:
kind: python
libs: {}
args:
input_var: "{{ workload.variable }}"
code: |
# Pure Python code - no imports, no def main()
result = {"status": "success", "data": {"value": input_var}}
workflow:
- step: start
next:
- step: process
- step: process
tool:
kind: workbook
name: reusable_task
next:
- step: end
- step: end

Key Concepts

ConceptDescription
PlaybookTop-level workflow definition with metadata, workload, workbook, and workflow
WorkloadGlobal variables merged with payload, available via Jinja2 templates
WorkbookLibrary of named reusable tasks
WorkflowOrdered list of steps defining execution flow
StepExecution unit with tool, args, vars, and routing
ToolAction executor (python, http, postgres, duckdb, etc.)

Template Namespaces

Access data in templates using these namespaces:

# Global variables from workload
"{{ workload.api_url }}"

# Extracted variables from vars blocks
"{{ vars.user_id }}"

# Previous step results
"{{ fetch_data.records }}"

# Current step result (in vars block)
"{{ result.status }}"

# Execution context
"{{ execution_id }}"

Step Routing

# Unconditional routing
next:
- step: next_step

# Conditional routing
next:
- when: "{{ result.status == 'success' }}"
then:
- step: success_handler
- when: "{{ result.status == 'error' }}"
then:
- step: error_handler
- step: default_handler # Fallback

See Also