Share a whylogs report

whylogs profiles datasets instead of copying them: sketches, counts, distributions, null rates — a summary small enough to log every run. Comparing two profiles gives you a drift report, which is the closest thing an ML team has to an early warning.

The warning then fires inside a notebook or a job log, which is the one place the people who caused the drift will never look.

Render the drift report

import whylogs as why
from whylogs.viz import NotebookProfileVisualizer

target = why.log(df_today).view()
reference = why.log(df_baseline).view()

viz = NotebookProfileVisualizer()
viz.set_profiles(target_profile_view=target, reference_profile_view=reference)
viz.write(
    rendered_html=viz.summary_drift_report(),
    html_file_name="drift",          # → drift.html
)

Self-contained HTML: per-column distributions, the drift statistic, the two histograms side by side. The side-by-side is the part that matters — a drift score alone is a number people argue with, and two overlaid distributions is an observation people act on.

Publish it

Drop drift.html into Comma, or from the job:

import requests, os

requests.patch(
    f"https://commareports.com/api/v1/reports/{os.environ['REPORT_ID']}",
    headers={"Authorization": f"Bearer {os.environ['COMMA_API_TOKEN']}"},
    json={"title": f"Drift — features_v2 — {run_date}",
          "html": open("drift.html").read()},
).raise_for_status()

Scripts run inside a sandboxed iframe (allow-scripts, no allow-same-origin), so the report's interactive column views keep working. See the API reference and publishing from CI.

Drift is a cross-team message

The useful thing about a drift finding is almost never "retrain the model". It is "column plan_tier gained a category on Tuesday" — a fact about an upstream pipeline, owned by a team that does not use your notebook, your MLflow, or your scheduler.

A URL is the only form of that message which survives the trip. With anchored comments, the reply lands on the column:

  • "We added enterprise_trial in the billing migration — expected."
  • "Null rate on region jumped because the CDN header changed."

That exchange, on the evidence, is the entire loop. See commenting on HTML.

One URL, a revision per run

PATCH the same report id from a scheduled job and the URL becomes the standing drift page for that dataset. Each run appends a revision, so the question "has this been creeping for a month or did it break yesterday?" is answered by scrubbing the history rather than by digging out old notebooks.

Pair it with a routine if you want the publish scheduled rather than wired into an existing job.

Who can see it

Per report: private, your team, anyone signed in at your domain, or anyone with the link. Profiles are summaries rather than rows, but a sketch over a small segment can still be revealing — use domain or team access. See sharing & access control.

Limits

  • Entry HTML: 5 MB. A report over hundreds of columns can approach it — profile the feature set the model actually uses.
  • Assets: 25 MB per file, 250 MB and 500 files total.
  • 60 requests/minute per token.

Try it

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

Publish a drift report →

Related