Skip to content

Quickstart

This walks you from nothing to a run visible in the portal in three steps.

In portal, open user menu → Get API token to get the key.

The SDK reads the key from the api_key argument or, more commonly, the METRANA_API_KEY environment variable:

Terminal window
export METRANA_API_KEY="your-api-key"
Terminal window
pip install metrana

(See Installation for platform details.)

The examples below are complete and runnable — they fabricate synthetic data, so you can copy-paste one, run it, and immediately see charts appear in the portal. Replace the fake numbers with your real ones once it works.

import math
import random
import metrana
metrana.init(
workspace_name="my-workspace",
project_name="my-project",
run_name="quickstart-ml",
config={"optimizer": "adam", "lr": 3e-4, "batch_size": 256}, # logged as run attributes
)
try:
for step in range(500):
# --- fake training signal: loss decays, accuracy climbs, both noisy ---
loss = math.exp(-step / 150) + random.uniform(0, 0.05)
acc = 1 - math.exp(-step / 120) - random.uniform(0, 0.05)
metrana.log("loss", loss) # one metric, auto-incrementing step
metrana.log({"accuracy": acc}) # a mapping logs several at once
finally:
metrana.close() # flush and shut down — always call this

The project and run are created automatically the first time you log to them. After the run finishes, find it in the runs table and open its charts — you’ll see a decaying loss and a rising accuracy.

import math
import random
import metrana
NUM_ENVS = 4 # M parallel environments
ROLLOUT_LEN = 16 # T timesteps collected per update
env_ids = [f"env{i}" for i in range(NUM_ENVS)]
metrana.init(workspace_name="my-workspace", project_name="my-project", run_name="quickstart-rl")
try:
episode = [0] * NUM_ENVS # current episode per env
for rl_step in range(200):
# --- fake rollout: an [M, T] block of rewards, one row per env ---
rewards = [
[math.sin(rl_step / 10) + random.uniform(-0.2, 0.2) for _ in range(ROLLOUT_LEN)]
for _ in range(NUM_ENVS)
]
# the whole rollout in ONE call: M envs x T timesteps, with a per-env
# episode list. Always log blocks like this — looping over envs or
# timesteps with single points ships the same data orders of magnitude
# less efficiently, for you and for the backend.
metrana.log_rl_environment_step(
"reward", rewards, rl_step=rl_step, env_id=env_ids, episode=episode
)
# end each env's episode roughly every 20 updates and log its return
if rl_step % 20 == 19:
for i in range(NUM_ENVS):
ep_return = random.uniform(0, 100) + rl_step
metrana.log_rl_episode(
"episode_return", ep_return, rl_step=rl_step,
env_id=env_ids[i], episode=episode[i],
)
episode[i] += 1
finally:
metrana.close()

RL data lands in the run’s Environments views. See RL metrics for the full two-level step model — the [M, T] / episode broadcasting rules, explicit env steps, and how episodes are entirely optional — and Logging at scale for why the vectorized call is the fast path.

The quickstart above is the minimum. For a production training job, add a disk spool so a backend outage never costs you data:

metrana.init(
workspace_name="ws", project_name="proj", run_name="run-001",
# survive sustained outages; size the spool for your disk
disk=metrana.DiskConfig("/var/spool/metrana", max_size_bytes=16 << 30),
)

See Disk spool.