Share a Weights & Biases report

W&B reports are the right internal artifact and the wrong external one. The link asks for a login, the login asks for a seat in your team, and the person you wanted to show the chart to is a client, a reviewer, or an advisor who will never have one.

Export the run history

import plotly.graph_objects as go
import wandb

api = wandb.Api()
fig = go.Figure()

for run_id in ("abc123", "def456"):
    run = api.run(f"my-team/my-project/{run_id}")
    hist = run.history(keys=["_step", "val/loss"], pandas=True).dropna()
    fig.add_trace(go.Scatter(x=hist["_step"], y=hist["val/loss"],
                             mode="lines", name=run.name))

fig.update_layout(title="val/loss — baseline vs new schedule",
                  xaxis_title="step", yaxis_title="val/loss")
fig.write_html("wandb.html", include_plotlyjs="inline")

include_plotlyjs="inline" keeps the file self-contained — a chart that fetches its own library from a CDN is a chart that renders blank on a locked-down network.

Publish it:

curl -fsS -X PATCH "https://commareports.com/api/v1/reports/$REPORT_ID" \
  -H "Authorization: Bearer $COMMA_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d "$(jq -n --rawfile html wandb.html \
        --arg title "Schedule comparison — $(date +%F)" '{title: $title, html: $html}')"

What the published copy adds

  • Anchored threads — the question about the step-8k divergence sits on the chart. See commenting on HTML.
  • Revisions — one report id per experiment family; each publish is kept.
  • Access per report — private, team-only, or domain-gated, decided per report rather than per workspace. See the sharing model.

Limits

  • Entry HTML: 5 MB. Inlined plotly.js is roughly 3 MB; downsample long histories with samples= on history().
  • Assets: 25 MB per file, 250 MB and 500 files per report.
  • 60 requests/minute per token.

Try it

Comma is free — unlimited reports, unlimited commenters, unlimited revision history.

Publish a run report →

Related