Skip to main content

Starlark Reference

Starlark is a deterministic, sandboxed subset of Python used in Lark steps. If you know Python, most of it will feel familiar. If you don't, this page covers everything you need.


The Basics

Every Lark step must assign a value to result. That value becomes the step's output.

result = "hello"          # scalar
result = # list[1][2][3]
result = {"key": "value"} # dict

If result is never assigned, the step fails.


Types

TypeExample
String"hello"
Integer42
Float3.14
BooleanTrue / False
List[1, 2, 3]
Dict{"key": "value"}
NoneNone

Strings

# Concatenation
full_name = "Hello " + "World"

# Length
n = len("hello") # → 5

# Split
parts = "alice@example.com".split("@")
# → ["alice", "example.com"]

# Access by index
first = parts # → "alice"
second = parts # → "example.com"[1]

# Slice
sub = "hello"[1:3] # → "el"

# Upper / lower
up = "hello".upper() # → "HELLO"
lo = "HELLO".lower() # → "hello"

# Strip whitespace
clean = " hello ".strip() # → "hello"

# Replace
new = "hello world".replace("world", "starlark")
# → "hello starlark"

# Check substring
"@" in "alice@example.com" # → True
"xyz" in "alice@example.com" # → False

# Convert to string
s = str(42) # → "42"
n = int("42") # → 42

Lists

items =[2][3][1]

# Access
first = items # → 1
last = items[-1] # → 3

# Length
n = len(items) # → 3

# Append
items.append(4) # →[3][4][2][1]

# Slice
sub = items[1:3] # →[2][3]

# Check membership
2 in items # → True
5 in items # → False

# Iterate
for item in items:
print(item)

# Build a new list from a SQL result
result = []
for row in step_0:
result.append(row["name"])

Dicts

user = {"id": 1, "name": "Alice", "email": "alice@example.com"}

# Access
user["name"] # → "Alice"

# Safe access with default
user.get("age", 0) # → 0 (field doesn't exist)

# Check key exists
"name" in user # → True
"age" in user # → False

# Add or update
user["role"] = "admin"

# Keys and values
user.keys() # → ["id", "name", "email"]
user.values() # → [1, "Alice", "alice@example.com"]

# Build a new dict from a row
row = step_0
result = {
"id": row["id"],
"name": row["name"],
}

Conditionals

# Basic if/else
if len(step_0) > 0:
result = step_0
else:
result = {}

# Inline conditional (ternary)
status = "found" if len(step_0) > 0 else "empty"

# Multiple conditions
if score > 90:
grade = "A"
elif score > 75:
grade = "B"
else:
grade = "C"

Loops

# Iterate over a list
result = []
for row in step_0:
result.append({
"id": row["id"],
"name": row["name"],
})

# Iterate with index
for i, row in enumerate(step_0):
print(i, row["name"])

# Loop over a range
for i in range(5):
print(i) # 0, 1, 2, 3, 4

# Filter while iterating
result = []
for row in step_0:
if row["active"] == True:
result.append(row)

Functions

# Define a function
def mask_email(email):
parts = email.split("@")
return parts + "***@" + parts[1]

# Call it
masked = mask_email("alice@example.com")
# → "a***@example.com"

# Use in a loop
result = []
for row in step_0:
result.append({
"id": row["id"],
"email": mask_email(row["email"]),
})

Accessing Step Data

SQL steps return a list of dicts — one dict per row:

# step_0 shape:
# [
# {"id": 1, "name": "Alice", "email": "alice@example.com"},
# {"id": 2, "name": "Bob", "email": "bob@example.com"},
# ]

# Access first row
first_row = step_0

# Access a field
name = step_0["name"] # → "Alice"

# Check if result is empty
if len(step_0) == 0:
result = []
else:
result = step_0

Accessing Request Input

# GET — query parameters
user_id = input.user_id
status = input.status

# POST — request body fields
name = input.name
email = input.email

# Safe access with default
page = input.get("page", 0)

Loading Modules

load("math", "upby10")
load("strings", "slugify")

# Must be at the top of the code block — before any other code

See Starlark Built-in Modules for the full module list.


What Starlark Does Not Support

Not supportedAlternative
importUse load()
f-strings — f"hello {name}"Concatenation — "hello " + name
try / exceptCheck with if before accessing
classUse dicts
Generators / comprehensionsUse for loops with append
Global mutable stateAll state is local to the step
None as dict valueUse "" or 0 as empty placeholders
tip

If something works in Python but not in Starlark, check this list first. The most common mistake is using f-strings or try/except.