Skip to content

Quickstart

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

In your workspace, open Settings → API keys and create a key with the ingestion:write scope. It’s shown only once — copy it somewhere safe.

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
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):
for i in range(NUM_ENVS):
# one per-environment-step reward for env i this update
reward = math.sin(rl_step / 10) + random.uniform(-0.2, 0.2)
metrana.log_rl_environment_step(
"reward", reward, rl_step=rl_step, env_id=env_ids[i], episode=episode[i]
)
# end an episode roughly every 20 updates and log its return
if rl_step % 20 == 19:
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 — including the vectorized form that logs all environments in a single call, and how episodes are entirely optional.

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",
disk="/var/spool/metrana", # survive sustained outages
)

See Disk spool.