Docs menu

Reference

Python SDK reference

Every class, function and method in slowapp_kit, the Python SDK for slowapps, and the slowapp_sdk checking tools.

The Python SDK, slowapp_kit, implements the container contract for Python apps. It reads the run’s environment, checks every card before writing it, and turns exceptions into the right exit codes. It ships in the base images at /opt/slowapp.

import slowapp_kit as kit
from slowapp_kit import Card, BLACK, WHITE, YELLOW, RED

Jobs

NameWhat it does
@kit.job(name)Registers a function fn(ctx) as the job name.
kit.main(argv=None)Reads the command line and runs it: job <name> runs that job and exits with its code; serve starts the app’s web page. Call it at the bottom of your entry module.
@kit.route(method, pattern)Registers a web page route for serve. pattern is a regular expression matched against the whole path; the handler is fn(request, *groups) and returns (status, headers, body). See Settings, schedules and pages.
kit.log(*args)Prints to stderr, where the hub and the checking tools collect it.

Errors and exit codes

Raise these from a job to end it with a specific outcome:

ExceptionExit codeMeaning for the hub
(job returns normally)0Store what the job wrote.
kit.Unchanged3Nothing changed: keep the previous cards.
kit.Transient4Temporary failure, such as a network error: retry later.
kit.NeedsConfig5A setting, secret or sign-in is missing or was refused: wait until it changes.
kit.ContractError64The app broke the contract, for example a card in the wrong size.
any other exception1A bug: the traceback goes to stderr, and the hub retries with backoff.

The constants EXIT_OK, EXIT_UNCHANGED, EXIT_TRANSIENT, EXIT_NEEDS_CONFIG and EXIT_CONTRACT hold the codes.

The run context: ctx

Inputs

NameWhat it is
ctx.app, ctx.job, ctx.run_idThe app id, job name and run id.
ctx.reasonWhy the job runs: planner, schedule, manual, event or fixture.
ctx.modelive or fixture. ctx.fixture is True in a test render.
ctx.nowThe hub’s current time (fixed in a test render).
ctx.for_The time the cards will be shown. Draw for this.
ctx.deadlineWhen the job must be finished, or None. ctx.remaining() returns the seconds left, or None.
ctx.tzThe screen’s time zone, as a ZoneInfo.
ctx.feedsThe feeds wanted this run, as a list of Surface.
ctx.feed(name)The Surface for one feed, or None if this run doesn’t want it.
ctx.settingsYour app’s settings, with the manifest’s defaults filled in.
ctx.layoutThe screen’s layout, as a dictionary (/in/layout.json).
ctx.events()For an event job: the events to apply, as a list of dictionaries.
ctx.data, ctx.cache, ctx.outPaths of /data, /cache and /out.
ctx.manifestYour slowapp.toml, as a dictionary.

A Surface has feed, w, h, inks ("k4"), slot and key, and name gives the surface as text, for example "452x444.k4".

Drawing

NameWhat it does
ctx.canvas(surface, fill=WHITE)A new RGB Pillow image of the surface’s exact size.
kit.font(name, size)Loads a font from the base image, for example kit.font("DejaVuSans-Bold.ttf", 34).
BLACK, WHITE, YELLOW, REDThe four inks as RGB tuples. Draw only in these, and set fontmode = "1" on every ImageDraw so text has no grey edges.

Writing output

NameWhat it does
ctx.write_feed(feed, cards, valid_from=None, valid_until=None)Writes one feed’s cards. cards is a list of Card, home card first. valid_from defaults to ctx.now, valid_until to an hour later.
ctx.write_prompts(prompts, surface_feed="prompts")Writes questions and their answer cards. Needs the prompts grant. See Questions and answers.
ctx.write_summary(status="ok", lines=(), actions=())Sets what the hub’s app card shows. Each action is {"label": …, "job": …} and runs that job.
ctx.write_timing(next_change_at)Tells the hub when the content will next change.
ctx.write_cache_key(key)Writes a key; if it equals the last run’s, the hub keeps the previous cards.
kit.atomic_write(path, data)Writes a file safely (temporary file, sync, rename). Use it for anything you keep in /data.

Card(id, image, title, peek="", kind="", keep_s=None):

  • id: lowercase letters, digits, - and _, unique in the feed.
  • image: a Pillow image of the surface’s size, in the four inks.
  • title: required; shown in the strip when this card is next.
  • peek: an optional second line for the strip.
  • kind: leave empty. The first card is home and the rest are detail.
  • keep_s: how long a detail card stays before the slot goes back home.

write_feed raises ContractError if a card has the wrong size, a colour outside the inks, a bad or repeated id, or no title; if there are no cards or more than 32; or if valid_until isn’t after valid_from.

Fetching and secrets

NameWhat it does
ctx.fetch(name, fn)Live: calls fn(), saves the result to /data/snapshots/<name> and returns it. Test render: returns the saved copy from the fixture instead. A .json name stores and returns JSON; otherwise str or bytes.
ctx.exit_if_unchanged()Raises Unchanged if every input fetched so far, and the settings, are the same as at the last successful run.
ctx.http_get(url, timeout=60, headers=None)Returns the body as bytes. The timeout is cut to fit the deadline. Network errors raise Transient; HTTP 401 and 403 raise NeedsConfig. Refuses the network in a test render.
ctx.http_json(url, timeout=60, headers=None)As http_get, parsed as JSON.
ctx.secret(name, optional=False)Reads /run/secrets/<name>. Missing: raises NeedsConfig, or returns None if optional. In a test render returns fixture-<name>.

The Weather tutorial uses these together.

Lower-level helpers

kit.check_inks(img), kit.to_indexed(img), kit.encode_png(img), kit.check_png(data, size) and kit.blob_id(img) check and encode images the way write_feed does. kit.blob_id returns the id the hub will give a card’s pixels, which is useful in unit tests.

Running outside a container

Every path the SDK uses can be moved with an environment variable: SLOWAPP_STATE (/data), SLOWAPP_OUT (/out), SLOWAPP_IN (/in), SLOWAPP_CACHE (/cache), SLOWAPP_SECRETS (/run/secrets), SLOWAPP_MANIFEST (/app/slowapp.toml), SLOWAPP_FONTS (/opt/slowapp/fonts) and SLOWAPP_JOB_LOCK. Test without hardware shows a full command.

The checking tools: slowapp_sdk

python3 -m slowapp_sdk validate [DIR ...]
python3 -m slowapp_sdk fixture [DIR] --image IMAGE [--repeat] [--out DIR]
  • validate checks slowapp.toml against the schema and the cross-field rules. Unknown keys are errors, so a typo can’t silently drop a grant. It prints ok or FAIL for each folder, with any errors and warnings.
  • fixture renders every example in a container and checks the output; see Test without hardware. --repeat renders twice and requires identical pictures; --out sets the previews folder (default out/previews). It needs Pillow, and Podman or Docker.

Environment: SLOWAPP_ENGINE (podman or docker), SLOWAPP_PLATFORM (for example linux/arm/v7), SLOWAPP_TIMEOUT_SCALE.

Updates, now and then

A short note when there is a new board, a new slowapp, or kit news. Rarely more than one a month.