Manage streams
Load streams attached or kept, choose which stream in a project to run, and stop, start and remove them.
Every stream runs inside the machine’s runtime. The tatolab CLI asks the runtime to load, stop and forget streams; it never runs a stream itself. This page covers those commands, and the difference between an attached stream and a kept one.
Three commands that load a stream
Section titled “Three commands that load a stream”| Command | What happens | Use it when |
|---|---|---|
tatolab dev |
Loads the stream attached, and loads it again every time you save a .py file or pyproject.toml in the project |
You’re writing or changing the stream |
tatolab run |
Loads the stream attached, once | You want to run it for a while and watch its log |
tatolab run -d |
Hands the stream to the runtime to keep, and returns | It should keep running on its own |
All three run from the project folder and use the project’s .venv. The stream’s log records print in your terminal for dev and run.
Attached
Section titled “Attached”An attached stream lives as long as the command that loaded it. Press Ctrl-C, close the terminal, or kill the command, and the runtime stops the stream. If the runtime itself goes down, run exits with an error that says so; dev waits for the runtime to come back and loads the stream again.
A kept stream belongs to the machine. The runtime writes a record of it to its state folder: the graph your stream function built, the project’s Python environment, and the exposure of each port. It loads the stream again every time the runtime starts: at login, at boot, and after a crash. If you built from source, the runtime is the tatolabd in your terminal, so kept streams come back when you start it again.
tatolab run -dmotion_watcher kept (project /home/you/motion-watcher)Which stream to load
Section titled “Which stream to load”By default, run and dev load the one function decorated with @stream in the project’s stream.py. To load something else:
| You want | Run |
|---|---|
One of several streams in stream.py |
tatolab run stream.py:recorder |
| A stream in another file | tatolab run cameras.py:front_door, or tatolab run -f cameras.py if it has only one |
| A stream from an installed package | tatolab run acme_streams.rover:camera_rig |
| A project in another folder | tatolab run --dir ~/projects/motion-watcher |
| The same stream under another name | tatolab run --name motion_watcher_test |
--dir sets the project folder, where the runtime looks for .venv. It defaults to the current folder, and doesn’t search parent folders.
A stream’s name is its function’s name, made URL-safe, unless you pass --name. Names are unique on a machine: loading a second stream with a name already in use is refused, and the message says which project has it.
See what’s loaded
Section titled “See what’s loaded”tatolab streamsNAME STATE NODES PROJECTmotion_watcher kept 6 /home/you/motion-watcherfront_door attached 4 /home/you/camerasgarage stopped - /home/you/cameras| State | Means |
|---|---|
attached |
Running, and lives as long as the command that loaded it |
kept |
Running, and the runtime loads it again whenever it starts |
stopped |
A kept stream you stopped. It stays stopped, across restarts too, until you start it. |
failed |
A kept stream the runtime stopped loading. The reason is printed below the table. |
Stop, start, remove
Section titled “Stop, start, remove”tatolab stop garage # unload it; a kept stream stays stopped until you start ittatolab start garage # load a stopped stream again, or retry a failed onetatolab rm garage # unload it and forget itstop on an attached stream ends it, the same as pressing Ctrl-C in its terminal. rm is the only command that makes the runtime forget a kept stream.
Change a kept stream
Section titled “Change a kept stream”The runtime keeps the graph from the moment you ran tatolab run -d. Editing the project afterwards doesn’t change the running stream, and neither do changes an agent makes to the live graph: after a restart, the runtime loads the recorded graph.
To pick up changes, run tatolab run -d again from the project folder. For the same project and stream function, that replaces the record with the new version.
A kept stream holds its name even while it’s stopped, so to work on one with tatolab dev, remove it first (tatolab rm motion_watcher), and tatolab run -d again when you’re done. Or run the development copy under another name (tatolab dev --name motion_watcher_dev), as long as the copy doesn’t need a device the kept stream has open, such as a camera.
When a kept stream fails
Section titled “When a kept stream fails”A kept stream is marked failed, and skipped when the runtime starts, when:
- it was involved in the runtime’s last two crashes in a row (a clean stop or restart of the runtime resets the count), or
- it can’t be loaded at all, for example because its project’s
.venvwas deleted.
Every other stream still starts. tatolab streams shows the reason:
garage failed: <the reason>. `tatolab start garage` retries it, `tatolab rm garage` forgets it.Fix the cause, then tatolab start garage.
The edit loop in detail
Section titled “The edit loop in detail”tatolab dev watches the project’s .py files and pyproject.toml. After each save:
- the runtime runs your stream function again in the project’s
.venv; - if that works, it replaces the running stream with the new one;
- if it fails, for example a syntax error in
stream.pyor a node module, the error prints and the previous version keeps running until a save that works. If no version has run yet,devprintsno stream is loaded — fix it and save again.
Errors that happen once the stream is running, like a GLSL mistake in an effect’s setup, appear in the stream’s log, in the same terminal.
The runtime
Section titled “The runtime”Every command on this page needs the runtime running. Without it, each one stops at once:
error: no runtime is running on this machine: nothing answers at /run/user/1000/streamlib/local-api.sock. Start one by running `tatolabd` in a terminal.How the runtime starts depends on how you installed it: the Tatolab app on a Mac, a systemd user service on Linux, or tatolabd in a terminal for a source build. See Install.