Introduction¶
o‑o is a command line interface for running jobs on ephemeral cloud instances with tracked inputs and outputs. Building data or MLOps pipelines is as simple as stringing together multiple commands, as easily as running locally, but with the power of cloud compute and storage.
Highlights¶
- Support for Scaleway and Google Cloud (more to come...)
- Easily run any command in any language in cloud compute environments
- Flexible. Define your own run environments with Docker images and machine types
- Traceable. Trace all inputs and outputs to the commands that produced them
- You control your data. Data and source code is stored in your managed buckets
Examples¶
Let's see o-o in action, first follow the installation
instructions. Then define a run environment and datastore (for
Scaleway or Google Cloud) in an .ooconfig file:
Hello world¶
We are now able to run a simple hello world example in our configured environment:
And that's it. This is an extremely inefficient hello world, and it will likely take a couple of minutes to complete, but it demonstrates how to easily run commands in a cloud environment (under the hood, o-o started and configured our environment, executed the command, and deleted the environment).
Multi-step pipelines¶
The real power of o‑o comes when stringing together commands into
data pipelines. So let's try a multi-step example to demonstrate connecting
outputs to inputs of another step. The following steps create files in the
special o://output/ directory:
We can see the history of our runs with o-o run --list:
Note
cn7gnwiapo, ntus965ryy and cxdbx8am38 are unique identifiers that will be
different for your runs. Similar to Git commits, a shortened version of the
full 45 character identifier is printed here. While using o‑o
commands, you only need enough characters to uniquely identify a run.
o://output/ is the output space for the current step, any files placed in
this directory are copied to the configured datastore. To use these files as
inputs, we reference them with the run id (ntus965ryy and cxdbx8am38). For
example, a third step prints out the files contents:
$ o-o run --message "print files" -- \
'cat o://ntus965ryy/hello.txt && cat o://cxdbx8am38/world.txt'
Hello
World
Tip
To avoid having to lookup run ids of our inputs (hello.txt and world.txt), you can tag runs with more suitable and memorable names.
Again, we can show our run history:
$ o-o run --list
cn7gnwiapo example run
ntus965ryy create hello
cxdbx8am38 create world
7it9dmgncy print files
and get more detailed information of our "print files" step with o-o show:
$ o-o show 7it9dmgncy --inputs
Run 7it9dmgncynuu7j54njgizi5s1ai3b3ajg4auwbw5oggc
Creator: Jon Doe <mail@example.com>
Started: Sun, 1 Feb 10:00:00 2026 -0500
Ended: Sun, 1 Feb 10:02:00 2026 -0500
Command: cat o://ntus965ryy/hello.txt && cat o://cxdbx8am38/world.txt
print files
Inputs:
|\
o | cxdbx8am38 create world
/
o ntus965ryy create hello
GPU environments¶
It is easy to run commands on GPU environments. Simply configure an environment
with a machine type with GPUs included. For example, let's add a new environment
with a L4 GPU machine type to our .ooconfig:
project: test-project
environments:
- name: my-simple-env
provider: Scaleway
image: docker.io/debian:stable-slim
machinetype: STARDUST1-S
region: fr-par-1
default: true
- name: my-gpu-env
provider: scaleway
image: docker.io/nvidia/cuda:11.0.3-base-ubuntu20.04
machinetype: L4-1-24G
region: fr-par-1
datastores:
- name: my-datastore
provider: Scaleway
bucket: o-o-data
region: fr-par
default: true
project: test-project
environments:
- name: my-simple-env
provider: gcp
image: docker.io/debian:stable-slim
machinetype: e2-highcpu-2
region: northamerica-northeast1-b
default: true
- name: my-gpu-env
provider: gcp
image: docker.io/nvidia/cuda:11.0.3-base-ubuntu20.04
machinetype: g2-standard-4
region: northamerica-northeast1-b
datastores:
- name: my-datastore
provider: gcp
bucket: o-o-data
default: true
We can now run GPU workloads with the new my-gpu-env environment:
$ o-o run --environment my-gpu-env --message "try gpu" -- nvidia-smi --list-gpus
GPU 0: NVIDIA L4 (UUID: GPU-11f9a1d6-7b30-e36e-d19a-ebc1eeaa1fe1)
And that's the basics. Find out more with o-o --help and in this documentation.