Module reference
Tetra provides Starlark modules for fetching and parsing data, formatting
values, protecting secrets, and rendering the final display. Import a module
with load before using it:
load("render.star", "render")
The second argument selects an exported symbol. Assign it to another local name when an alias reads better:
load("render.star", r = "render")
Starlib modules
Tetra includes a subset of the Starlib standard library.
| Module | Purpose |
|---|---|
bsoup.star | Parse and traverse HTML with a Beautiful Soup-style API. |
compress/gzip.star | Decompress gzip data. |
compress/zipfile.star | Read compressed ZIP archives. |
encoding/base64.star | Encode and decode Base64 data. |
encoding/csv.star | Decode CSV data. |
encoding/json.star | Encode and decode JSON data. |
hash.star | Generate MD5, SHA-1, and SHA-256 hashes. |
html.star | Query HTML with a jQuery-style API. |
math.star | Use mathematical functions and constants. |
re.star | Match and transform text with regular expressions. |
time.star | Parse, format, and calculate with dates and times. |
Starlib HTTP
Tetra includes a caching-aware version of Starlib's HTTP client. Pass
ttl_seconds to cache a response and keep outgoing request rates reasonable.
| Module | Purpose |
|---|---|
http.star | Make HTTP requests with response caching. |
For example, cache a JSON response for one hour:
load("http.star", "http")
def fetch_status():
response = http.get(
"https://status.example.com/api/status",
ttl_seconds = 3600,
)
if response.status_code != 200:
fail("Status request failed: %d" % response.status_code)
return response.json()
Cache
cache.star stores string values between app executions. Prefer HTTP's
built-in response caching for requests; use this module for derived or
non-HTTP values. Serialize structured data before storing it.
| Function | Returns | Purpose |
|---|---|---|
get(key) | str or None | Read an unexpired value. |
set(key, value, ttl_seconds=60) | — | Store a string value with a TTL in seconds. |
The cache belongs to the app, not an individual installation. Include any installation-specific inputs in the key to prevent values from colliding.
load("cache.star", "cache")
def next_counter():
stored = cache.get("counter")
current = int(stored) if stored != None else 0
current += 1
cache.set("counter", str(current), ttl_seconds = 3600)
return current
HMAC
hmac.star authenticates a string with a secret key using
HMAC.
| Function | Returns | Purpose |
|---|---|---|
md5(key, string) | str | Generate an HMAC-MD5 digest. |
sha1(key, string) | str | Generate an HMAC-SHA-1 digest. |
sha256(key, string) | str | Generate an HMAC-SHA-256 digest. |
load("hmac.star", "hmac")
signature = hmac.sha256("secret", "message")
Humanize
humanize.star converts dates, quantities, byte counts, and number values
into display-friendly strings.
| Function | Purpose |
|---|---|
time(date) | Format a date relative to now. |
relative_time(date1, date2, label1?, label2?) | Describe the difference between two dates, optionally using labels. |
time_format(format, date?) | Convert a Java-style date format to a Go layout and optionally format a date. |
day_of_week(date) | Return the weekday from 0 for Sunday through 6 for Saturday. |
bytes(size, iec?) | Format a byte count with SI or optional IEC units. |
parse_bytes(formatted_size) | Convert a formatted byte value back to a number. |
comma(num) | Add thousands separators to a number. |
float(format, num) | Format a floating-point value with a pattern. |
int(format, num) | Format an integer with a pattern. |
ordinal(num) | Format a number as an ordinal such as 1st. |
ftoa(num, digits?) | Convert a float to text without trailing zeros. |
plural(quantity, singular, plural?) | Combine a quantity with the correct singular or plural label. |
plural_word(quantity, singular, plural?) | Return the correct singular or plural word. |
word_series(words, conjunction) | Join words into an English list. |
oxford_word_series(words, conjunction) | Join words into an English list with an Oxford comma. |
url_encode(str) | Percent-encode text for a URL. |
url_decode(str) | Decode percent-encoded URL text. |
load("humanize.star", "humanize")
storage = humanize.bytes(82854982)
visits = humanize.comma(123456)
position = humanize.ordinal(3)
XPath
xpath.star parses XML and extracts text or nested nodes with XPath queries.
| Function | Returns | Purpose |
|---|---|---|
loads(doc) | xpath object | Parse an XML string. |
Parsed XPath objects provide these methods:
| Method | Returns | Purpose |
|---|---|---|
query(path) | str | Read the first matching node's text. |
query_all(path) | [str] | Read text from all matching nodes. |
query_node(path) | xpath object | Read the first matching node for further queries. |
query_all_nodes(path) | [xpath] | Read all matching nodes for further queries. |
load("xpath.star", "xpath")
FEED = """
<forecast>
<day><high>24</high></day>
<day><high>27</high></day>
</forecast>
"""
def forecast_highs():
document = xpath.loads(FEED)
return document.query_all("/forecast/day/high")
Render
render.star contains the widgets used to compose the 64 × 32 display. Every
app returns a render.Root from main.
load("render.star", "render")
def main(config):
return render.Root(
child = render.Box(
width = 64,
height = 32,
color = "#111827",
child = render.Text("Hello", color = "#f9fafb"),
),
)
See the widget reference for every available render primitive.
Schema
schema.star declares the settings displayed when someone configures an app.
The saved values are passed to main(config) under each field's identifier.
load("render.star", "render")
load("schema.star", "schema")
def main(config):
return render.Root(
child = render.Text(config.get("message", "Hello")),
)
def get_schema():
return schema.Schema(
version = "1",
fields = [
schema.Text(
id = "message",
name = "Message",
desc = "Text shown on the display",
icon = "message",
default = "Hello",
),
],
)
Secret
secret.star decrypts values created with tetra encrypt. A secret decrypts
in the SolidPixels render environment for its intended app. Local rendering
returns None, so accept a development value through config when needed.
| Function | Returns | Purpose |
|---|---|---|
decrypt(value) | str or None | Decrypt an app-bound encrypted value. |
load("secret.star", "secret")
ENCRYPTED_API_KEY = "..."
def api_key(config):
return secret.decrypt(ENCRYPTED_API_KEY) or config.get("dev_api_key")
Never commit a plaintext production secret to an app.
Sunrise
sunrise.star calculates solar events and elevation for a location.
| Function | Purpose |
|---|---|
sunrise(lat, lng, date) | Calculate sunrise for a location and date. |
sunset(lat, lng, date) | Calculate sunset for a location and date. |
elevation(lat, lng, time) | Calculate the sun's elevation at a point in time. |
elevation_time(lat, lng, elev, date) | Return the two times the sun reaches an elevation, or None when it does not. |
load("sunrise.star", "sunrise")
load("time.star", "time")
def solar_times(latitude, longitude):
today = time.now()
return (
sunrise.sunrise(latitude, longitude, today),
sunrise.sunset(latitude, longitude, today),
)
Random
random.star generates pseudorandom integers. Tetra automatically seeds the
generator for each execution; call seed when you need a repeatable sequence.
| Function | Returns | Purpose |
|---|---|---|
seed(value) | — | Replace the current seed. |
number(min, max) | int | Return a value between min and max; min must be non-negative and lower than max. |
load("random.star", "random")
def choose_message():
messages = ["Hello", "Welcome", "Good day"]
return messages[random.number(0, len(messages))]
QR code
qrcode.star creates compact QR codes as image data that can be passed to
render.Image. Keep the encoded value short because the display supports only
small QR versions.
| Function | Returns | Purpose |
|---|---|---|
generate(url, size, color?, background?) | image data | Generate a QR code from a short URL or text value. |
Supported sizes are "small" (21 × 21), "medium" (25 × 25), and "large"
(29 × 29).
load("qrcode.star", "qrcode")
load("render.star", "render")
def main(config):
image = qrcode.generate(
url = "https://solidpixels.io?utm_source=tetra_example",
size = "large",
color = "#ffffff",
background = "#000000",
)
return render.Root(
child = render.Box(
width = 64,
height = 32,
child = render.Image(src = image),
),
)
