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.