Skip to main content

Jinja in Attributes

@check and @assert use Jinja syntax to specify invariants (properties that should always hold true).

The this Keyword​

  • Field attributes: this refers to the field value
  • Block attributes: this refers to the entire object
class Student {
first_name string @assert({{ this|length > 0 }}) // this = first_name
age int @check(old_enough, {{ this > 5 }}) // this = age
@@check(age_threshold, {{ this.age > 12 }}) // this = Student object
}

Available Filters​

FilterDescription
absAbsolute value
capitalizeFirst letter uppercase
escapeHTML escape
firstFirst item of list
lastLast item of list
default(x)Returns x when undefined
floatConvert to float (or 0.0)
intConvert to int (or 0)
joinConcatenate list of strings
lengthList/string length
lowerLowercase
upperUppercase
map(filter)Apply filter to each item
maxMaximum of list
minMinimum of list
regex_match("regex")True if matches regex
reject("test")Filter out failing items
reverseReverse list/string
roundRound to nearest int
select("test_name")Keep passing items
sumSum of numbers
titleTitle Case
trimRemove whitespace
uniqueRemove duplicates

Common Patterns​

function GenerateStory(subject: string) -> string {
client "openai/gpt-4o"
prompt #"Write a story about {{ subject }}"#
}

test HorseStory {
functions [GenerateStory]
args {
subject "Equestrian team coming-of-age story"
}
@@assert({{ this|lower|regex_match("horse") }})
}

Exact Match​

class Person {
first_name string
last_name string
}

test ExtractJohnDoe {
functions [ExtractPerson]
args {
description "John Doe is a 5'6\" man."
}
@@assert({{ this.first_name|regex_match("^John$") }})
@@assert({{ this.last_name == "Doe" }})
}

Sum Validation​

class Receipt {
items Item[]
tax_cents int
total_cents int
}

class Item {
name string
price_cents int
}

test SmallReceipt {
functions [ExtractReceipt]
args {
text_receipt "Affogato: $8.50. Tax: $1. Total: $9.50"
}
@@assert({{ this.items|map(attribute="price_cents")|sum + this.tax_cents == this.total_cents }})
}

See Also​