Skip to content
helmstudio
Contents

Quickstart

From an empty directory to a studio of your own, running under helm dev and recording its first output.

You need macOS on Apple Silicon, or Linux on x86-64 or ARM64, with Python 3.9 or newer, curl, and a network connection to install. Nothing here needs a clone of helmstudio, Go, a GPU, a model or a Hugging Face account.

1. Install helm

helm validates manifests, and runs a studio with no daemon. The installer downloads the newest release for this machine, checks it against the release's checksums, runs it once, and puts it in ~/.local/bin.

quickstart/01-install-helm.sh not run by the gate — it needs the network; the gate builds helm from the checkout it tests and puts it on the path instead
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/janishar/helmstudio/main/installer/install.sh)"

If ~/.local/bin is not on your PATH, the installer prints the line to add. Install helm covers installing a particular version, upgrading and uninstalling.

2. Make a directory and a Python environment

A studio runs in its author's environment. helm dev never makes one, or changes one.

quickstart/02-environment.sh
mkdir hello-studio
cd hello-studio
python3 -m venv .venv
source .venv/bin/activate

3. Install the runtime SDK

The Python client comes from PyPI, and uses the standard library and nothing else.

quickstart/03-install-sdk.sh not run by the gate — it needs the network; the gate puts the same package from the checkout it tests on the environment's path instead
pip install helm-runtime-sdk

4. Get the example studio

The example is about the smallest studio that does something: it makes an image from a prompt, and records it. Download its two files into the directory:

quickstart/04-get-example.sh not run by the gate — it needs the network; the gate copies the same two files from the checkout it tests instead
curl -fsSLO https://raw.githubusercontent.com/janishar/helmstudio/main/site/samples/hello-studio/helmstudio.yaml
curl -fsSLO https://raw.githubusercontent.com/janishar/helmstudio/main/site/samples/hello-studio/studio.py

Its manifest says what it is, what it asks helmstudio for, and how to run it:

hello-studio/helmstudio.yaml
# A studio helmstudio can run: one process, asking for two capabilities.
id: hello-studio
name: hello studio
description: Makes a small image from a prompt, and records it with its parameters.
kinds: [image]
license: MIT
# Where the studio's repository will live. helm dev runs the checkout it is
# given, and never clones this.
repo: https://github.com/you/hello-studio
requires:
  os: [darwin, linux]
  arch: [arm64, amd64]
  tools: [python3]
  ram_gb: 1
  disk_gb: 1
peak_ram_gb: 1
runtime:
  framework: other
  backends: [cpu]
sdk: { runtime: "^1" }
capabilities: [assets, gallery]
processes:
  - name: studio
    role: main
    # helm dev runs this in the manifest's own directory, and gives it a free
    # port, preferring 8765.
    cmd: "python3 studio.py --port {port}"
    port: { prefer: 8765 }
    health: { path: /healthz, timeout_s: 30 }
    ui: /

Its code is a web server. The two calls that make it a studio are these, and the rest of the file — an argument parser, a request handler, and twenty lines that draw a PNG by hand so the example needs no image library — is the studio's own business.

hello-studio/studio.py#sdk
def make(prompt, seed):
    """Write the image to the stage, adopt it, and record it."""
    stage = os.environ["HELM_STAGE_DIR"]
    path = os.path.join(stage, "hello-%d.png" % seed)
    with open(path, "wb") as f:
        f.write(make_png(prompt, seed))

    # Adopting moves the file into helmstudio's asset store without copying it.
    asset = helm.assets.adopt({"path": path, "kind": "image"})

    # The item is what the gallery shows, with what made it.
    item = helm.gallery.add({
        "kind": "image",
        "asset_id": asset["id"],
        "title": prompt,
        "params": {"prompt": prompt, "seed": seed, "width": 256, "height": 256},
    })
    return {"item_id": item["id"], "asset_id": asset["id"]}

5. Run it

helm dev keeps the studio's data in .helm, beside the manifest. It serves the platform API on a free local port, gives the studio a token for the two capabilities its manifest asks for, starts its process, and waits for its health check.

quickstart/05-run.sh
helm dev -f helmstudio.yaml

It prints the API's address and where the data is, then the studio's output, each line prefixed with its process's name — first the command it started, then what the studio itself printed:

quickstart/05-output.txt
helm dev: hello-studio is starting; studio API http://127.0.0.1:…/api/v1, data in …/hello-studio/.helm
studio | [helmstudio …: starting studio in …/hello-studio: python3 studio.py --port 8765]
studio | hello studio: http://127.0.0.1:8765

The studio asked for port 8765. If something else has it, helm dev gives the studio another, and the line above says which — use that one below. Leave it running, and use a second terminal for the rest. Ctrl-C stops it.

6. Make something

quickstart/06-make.sh
curl -s -X POST http://127.0.0.1:8765/make -d '{"prompt": "a lighthouse at dusk", "seed": 7}'

The answer names the gallery item and the asset it holds.

7. See it recorded

quickstart/07-items.sh
curl -s http://127.0.0.1:8765/items

The item comes back with the prompt and the seed that made it. That is provenance: wherever the item is shown later, what made it is shown with it.

8. Check it against the criteria

quickstart/08-validate.sh
helm validate -criteria helmstudio.yaml

helm validate checks a manifest against the schema and the rules the schema cannot express. With -criteria it also scores the fifteen criteria a published studio is held to, as far as a manifest can answer them. The example fails two: it declares no test profile, because the harness that would run one is not built, and it pins no ref, because it has no repository yet. Publish a studio explains both.

Next