Skip to content
Merged
Show file tree
Hide file tree
Changes from 32 commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
94196de
refactor(admin): shared fetch_chargeback_report helper in utils
LeoRoccoBreedt Jul 17, 2026
50e19dd
feat(growth-report): collect Opik TRACE_COUNT alongside SPAN_COUNT
LeoRoccoBreedt Jul 17, 2026
f78fdf0
feat(growth-report): add multi-series lines chart primitive
LeoRoccoBreedt Jul 17, 2026
ecaa4aa
feat(growth-report): add admin_growth_users parse + adoption/leaderbo…
LeoRoccoBreedt Jul 17, 2026
9286971
feat(growth-report): people section (active/adoption) + CLI args + re…
LeoRoccoBreedt Jul 17, 2026
e003b20
fix(growth-report): degrade people layer on malformed chargeback; tig…
LeoRoccoBreedt Jul 17, 2026
9ddb39c
feat(growth-report): people active/adoption/capability over-time series
LeoRoccoBreedt Jul 17, 2026
79e7d81
feat(growth-report): leaderboards section (workspace + user, top/bott…
LeoRoccoBreedt Jul 17, 2026
932f4d6
feat(growth-report): personal-vs-service-account split via admin API …
LeoRoccoBreedt Jul 17, 2026
4f71226
fix(growth-report): honest service-account degrade + anchored heurist…
LeoRoccoBreedt Jul 17, 2026
05609f6
feat(growth-report): optional personal-workspace exclusion (--exclude…
LeoRoccoBreedt Jul 17, 2026
7da0f8a
style(growth-report): apply black/isort formatting; drop unused test …
LeoRoccoBreedt Jul 17, 2026
c2bc157
fix(growth-report): hoist leaderboard_users; drop dead hint; bound -s…
LeoRoccoBreedt Jul 17, 2026
568b4ab
docs(growth-report): document people-layer CLI flags and sections in …
LeoRoccoBreedt Jul 17, 2026
090f4e2
refactor(growth-report): org-overview section, growth KPIs, cleaner l…
LeoRoccoBreedt Jul 21, 2026
8c3f86d
refactor(growth-report): chargeback-only report.py; remove SDK data e…
LeoRoccoBreedt Jul 24, 2026
a58df57
refactor(growth-report): strip SDK rendering from render.py
LeoRoccoBreedt Jul 24, 2026
4351558
refactor(growth-report): drop --platforms/--limit/--no-users; exit no…
LeoRoccoBreedt Jul 24, 2026
aa0d206
docs(growth-report): chargeback-only methodology; admin key required
LeoRoccoBreedt Jul 24, 2026
0c9d803
test(growth-report): chargeback-shape the _sample_report_data render …
LeoRoccoBreedt Jul 24, 2026
f772083
docs(growth-report): drop reference to the local SDK-preservation branch
LeoRoccoBreedt Jul 24, 2026
8b8a552
fix(growth-report): address PR review findings
LeoRoccoBreedt Jul 24, 2026
0d8d877
fix(growth-report): correctness fixes from code review (workflow + Baz)
LeoRoccoBreedt Jul 24, 2026
b680c8f
refactor(growth-report): share window-growth math between KPIs
LeoRoccoBreedt Jul 24, 2026
9648b25
fix(growth-report): correct churn growth-rate base + validate chargeb…
LeoRoccoBreedt Jul 28, 2026
a1b5a8b
fix(growth-report): implement PR #26 review findings (dsblank)
LeoRoccoBreedt Jul 28, 2026
e398819
fix(growth-report): address dsblank re-review (URL builder + sweep)
LeoRoccoBreedt Jul 29, 2026
1864e4c
fix(migrate-users): catch malformed baseUrl instead of crashing
LeoRoccoBreedt Jul 29, 2026
dddacc9
fix(growth-report): narrow URL error handling; keep series axes aligned
Jul 30, 2026
f3c0db7
fix(migrate-users): accept on-prem http bases via --url/--source-url
Jul 30, 2026
a6e866d
Version 3.6.9: chargeback-only growth-report
Jul 30, 2026
08cbb26
fix(growth-report): chart-vs-KPI mismatch; one shared server-URL rule
Jul 30, 2026
665c3eb
fix(admin): redact URL credentials; fallback total must follow the KPI
Jul 30, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 42 additions & 34 deletions README-ADMIN.md
Original file line number Diff line number Diff line change
Expand Up @@ -125,10 +125,14 @@ When using the `--app` flag, an interactive web interface is launched where you

## growth-report

Generate a cross-platform use-case growth & adoption report — Opik projects, EM projects,
and MPM monitored models — as a single self-contained HTML page. This is distinct from
`usage-report` (an experiment-count PDF): `growth-report` tracks *how many use cases exist
and how fast they're being created*, per workspace/department, across all three products.
Generate an organization growth & adoption report as a single self-contained
HTML page, built entirely from the **admin chargeback report**. Distinct from
`usage-report` (an experiment-count PDF): `growth-report` gives an org-wide view
of workspaces, users, and platform adoption, broken down by workspace/department.

**Requires an admin API key.** The report is derived entirely from the admin
chargeback endpoint; with a non-admin key the command prints an error and exits
non-zero — there is no fallback.

### Basic Usage

Expand All @@ -138,60 +142,64 @@ cometx admin growth-report my-workspace
cometx admin growth-report my-workspace another-workspace
```

If no workspace is given, all workspaces visible to the current API key are used.
Chargeback data is org-wide by default. If one or more workspaces are given, the
report is scoped to just those workspaces.

### Options

- **`WORKSPACE ...`**: Zero or more workspaces to include. If omitted, resolved via `get_workspaces()`.
- **`--units {month,week,day,hour}`**: Chart bucket granularity (default: `month`). Charts always render **all-time** history at this granularity — this is a separate concept from `--window`, below.
- **`--window WINDOW`**: Relative analysis window for the KPI numbers, e.g. `7d`, `14d`, `30d`, `90d`, `2w`, `6m`, `1y` (default: `7d`). Format is `\d+[dwmy]`: `d`=days, `w`=weeks (×7 days), `m`=months (approximated as 30 days), `y`=years (approximated as 365 days). The month/year approximation is intentional — the window is only used to compute an "installed base before window" cutoff, not calendar-exact arithmetic.
- **`--platforms PLATFORMS`**: Comma-separated platforms to include (default: `em,opik,mpm`).
- **`WORKSPACE ...`**: Zero or more workspaces to scope the report to. If omitted, the report is org-wide.
- **`--units {month,week,day,hour}`**: Chart bucket granularity (default: `month`). Charts render all-time history at this granularity — a separate concept from `--window`.
- **`--window WINDOW`**: Relative analysis window for the growth KPIs, e.g. `7d`, `14d`, `30d`, `90d`, `2w`, `6m`, `1y` (default: `7d`). Format `\d+[dwmy]`: `d`=days, `w`=weeks (×7 days), `m`=months (≈30 days), `y`=years (≈365 days).
- **`--output PATH`**: Output HTML file path (default: `growth_report.html`).
- **`--limit N`**: Limit the number of workspaces processed — useful for a fast smoke-test run.
- **`--active-window WINDOW`**: Activity window for the users layer, e.g. `30d`/`60d` (default: `60d`). A user counts as *active* when their last-used timestamp falls within this window.
- **`--leaderboard-top-n N`**: Top/bottom N size for the leaderboards section (default: `5`).
- **`--exclude-personal`**: Drop workspaces whose name matches `--personal-pattern` from the chargeback data (default: off; has no effect without `--personal-pattern`).
- **`--personal-pattern REGEX`**: Regex used with `--exclude-personal` to identify personal-workspace names to drop, e.g. `'^user-'` (default: none).
- **`--no-open`**: Don't automatically open the generated HTML file after generation.

### The two time concepts

- **`--units`** is the *chart granularity*: every chart shows the complete all-time history bucketed at this resolution.
- **`--window`** is the *KPI analysis window*: Total/New/% Growth numbers compare "in the last `--window`" against "before the window." On the charts, the window is drawn as a shaded band overlaid on the all-time series, rather than filtering the data.
- **`--window`** is the *KPI analysis window*: the "New in {window} (% of base)" growth KPIs compare accounts/workspaces created in the last `--window` against those that existed before it.

### Growth rates

Growth and adoption rates are computed directly from use-case **creation timestamps**:
`pct_growth = new_in_window / count_before_window`, where `count_before_window` is the
number of use cases created before `window.start` and `new_in_window` is the number
created inside `[window.start, window.end]`.
The growth KPIs are computed from chargeback `createdAt` timestamps:
`new_in_window / count_before_window × 100`, where `count_before_window` is the
count that existed before `window.start` and `new_in_window` is the count created
inside `[window.start, window.end]`. Workspace creation is proxied from each
workspace's earliest member `createdAt`.

### Examples

```shell
# Full cross-platform report for all workspaces, default 7-day window
# Org-wide report, default 7-day window
cometx admin growth-report

# Just Opik + EM, 30-day window, for two workspaces
cometx admin growth-report --platforms em,opik --window 30d my-workspace another-workspace
# 30-day window, scoped to two workspaces
cometx admin growth-report --window 30d my-workspace another-workspace

# Write to a file without auto-opening
cometx admin growth-report --no-open --output growth.html

# Fast smoke-test run against a single workspace, don't auto-open
cometx admin growth-report --limit 1 --no-open --output growth.html my-workspace
# 30-day activity window and top/bottom-10 leaderboards, excluding personal
# workspaces named like "user-..."
cometx admin growth-report --active-window 30d --leaderboard-top-n 10 \
--exclude-personal --personal-pattern '^user-'
```

### Output

The growth report generates a single self-contained HTML file containing:

- A **unified section** ("Use cases across all platforms") with department/use-case KPIs, a stacked created-per-period chart broken down by kind (Opik/EM/MPM), a use-cases-by-department chart, and a breakdown table.
- Per-product **growth** sections (Opik / EM / MPM) with Total / New / % Growth KPIs, a new-use-cases bar chart, a cumulative area chart (both carrying the analysis window as a shaded band), and a breakdown table.
- Per-product **adoption** sections with secondary usage metrics — Opik span counts, EM experiment counts, MPM prediction volume — each broken down by project.
The report generates a single self-contained HTML file containing:

The breakdown tables follow one rule throughout: when more than one workspace is included,
tables break down **by workspace/department**; when only a single workspace is included,
tables break down **by individual use case** instead (a by-workspace table with one row
would be uninformative).
- An **Organization overview (chargeback)** section with org-wide KPIs (Total workspaces, Total EM projects, New in {window} (% of base), Active workspaces %), a workspace platform-mix chart (EM / Opik / both / neither), workspace total-vs-active and added-vs-deleted charts, and a by-workspace table.
- A **Users** section with Total / Active (`--active-window`) / Active % / New in {window} KPIs, plus active-vs-total, adoption-rate, per-capability, and user-churn charts.
- A **Leaderboards** section ranking workspaces (by experiments and EM projects, exact from chargeback) and users (by Opik spans and EM activity), as top-N and active-aware bottom-N. Metrics with no data are omitted.
- A **Personal vs Service accounts** section splitting experiments / data / spans between personal and service accounts. Service accounts are identified from the admin service-accounts API when available, falling back to a labeled regex heuristic; the source is shown in the panel hint.

### Caveats

- **EM "created" is a proxy.** The Comet API has no true EM project-creation timestamp, so an EM project's creation time is approximated as the earliest experiment start time in that project, falling back to the project's `lastUpdated` time if it has no experiments.
- **Workspace/department "created" is also a proxy** — the earliest use-case creation timestamp seen in that workspace, across all platforms.
- **The EM model-registry engagement panel is a snapshot**, not an over-time series ("Registered models" / "Model versions" per workspace) — it is kept in its own labeled panel and is **never** combined with MPM's monitored-model counts, even though both are "model" concepts.
- **MPM requires provisioning.** If the account/workspace has no MPM model-monitoring provisioned, the MPM collector degrades gracefully — an empty MPM section and `collectors.mpm: false` in the underlying report data — rather than failing the whole report.
- Opik and MPM collection require their optional SDKs (`opik`, `comet_mpm`). Install them with `pip install 'cometx[all]'` if not already available; any platform whose SDK can't be imported is silently dropped from `--platforms` (a note is printed to the console) so the report still succeeds with the remaining platforms.
- **Chargeback is required.** The whole report is derived from the admin chargeback report; without admin access the command errors out (non-zero exit).
- **Workspace "created" is a proxy** — the earliest member `createdAt` in that workspace, since chargeback has no workspace-creation timestamp. The added-vs-deleted "deleted" series is also a best-effort proxy (all members removed) and typically reads ~0.
- **"Total projects" counts EM projects only** — chargeback's per-workspace `projects[]` covers Experiment Management. Opik projects and MPM aren't represented there (Opik appears only as a per-user span count; MPM is absent), so the platform mix uses an Opik per-user proxy and excludes MPM.
- **The people layer degrades independently.** If the chargeback payload parses but a section's inputs are missing, a warning is printed and only that section is dropped — the rest of the report still generates.
67 changes: 43 additions & 24 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -580,51 +580,70 @@ cometx admin usage-report --app

#### growth-report

Generate a cross-platform use-case growth & adoption report (Opik projects, EM projects,
MPM monitored models) as a single self-contained HTML page. Distinct from `usage-report`
(experiment-count PDF): `growth-report` tracks *how many use cases exist and how fast
they're being created*, per workspace/department, across all three products.
Generate an organization growth & adoption report as a single self-contained HTML
page, built entirely from the **admin chargeback report**. Distinct from
`usage-report` (experiment-count PDF): `growth-report` gives an org-wide view of
workspaces, users, and platform adoption, per workspace/department.

**Requires an admin API key** — the report is derived entirely from the admin
chargeback endpoint, and with a non-admin key the command errors out (non-zero
exit).

```
cometx admin growth-report [WORKSPACE ...]
```

**Arguments:**
* `WORKSPACE` (optional, zero or more) - Workspaces to include. If omitted, all workspaces visible to the current API key are used (via `get_workspaces()`).
* `WORKSPACE` (optional, zero or more) - Workspaces to scope the report to. If omitted, the report is org-wide.

**Options:**
* `--units {month,week,day,hour}` - Chart bucket granularity (default: month). Charts always render **all-time** history at this granularity; this is unrelated to `--window` below.
* `--window WINDOW` - Relative analysis window for the KPIs, e.g. `7d`, `14d`, `30d`, `90d`, `2w`, `6m`, `1y` (default: `7d`). `d`=days, `w`=weeks (×7d), `m`=months (approximated as 30 days), `y`=years (approximated as 365 days) — the approximation is intentional, since the window only needs an "installed base before window" cutoff, not calendar-exact arithmetic.
* `--platforms PLATFORMS` - Comma-separated list of platforms to include (default: `em,opik,mpm`). Any of `em`, `opik`, `mpm`.
* `--units {month,week,day,hour}` - Chart bucket granularity (default: month). Charts render all-time history at this granularity; unrelated to `--window` below.
* `--window WINDOW` - Relative analysis window for the growth KPIs, e.g. `7d`, `14d`, `30d`, `90d`, `2w`, `6m`, `1y` (default: `7d`). `d`=days, `w`=weeks (×7d), `m`=months (≈30 days), `y`=years (≈365 days).
* `--output PATH` - Output HTML file path (default: `growth_report.html`).
* `--limit N` - Limit the number of workspaces processed (useful for a fast smoke-test run).
* `--active-window WINDOW` - Activity window for the users layer, e.g. `30d`/`60d` (default: `60d`). A user is *active* when their last-used timestamp falls within this window.
* `--leaderboard-top-n N` - Top/bottom N size for the leaderboards section (default: `5`).
* `--exclude-personal` - Drop workspaces whose name matches `--personal-pattern` from the chargeback data (default: off; no effect without `--personal-pattern`).
* `--personal-pattern REGEX` - Regex used with `--exclude-personal` to identify personal-workspace names to drop, e.g. `'^user-'` (default: none).
* `--no-open` - Don't automatically open the generated HTML file after generation.

**Two time concepts:**
* `--units` controls chart *granularity* — every chart shows the full all-time history bucketed at this resolution.
* `--window` controls the *analysis window* used for the KPI numbers (Total / New / % growth) — it's drawn as a shaded band on top of the all-time charts rather than filtering them out.

**Growth rates:** growth/adoption rates are computed from use-case **creation timestamps**
(`--window` boundary vs. each event's `created` time), not from a separate "installed base"
snapshot, so `pct_growth` is always `new_in_window / count_before_window`.
* `--window` controls the *analysis window* for the "New in {window} (% of base)" growth KPIs — accounts/workspaces created in the last `--window` vs. those that existed before it.

**Growth rates:** the growth KPIs are computed from chargeback `createdAt`
timestamps as `new_in_window / count_before_window × 100`. Workspace creation is
proxied from each workspace's earliest member `createdAt`.

**Report sections:** an **Organization overview (chargeback)** section (org-wide
KPIs, workspace platform mix, total-vs-active and added-vs-deleted charts, and a
by-workspace table), a **Users** section (Total / Active / Active % / New-in-window
KPIs plus over-time charts), a **Leaderboards** section (top-N and active-aware
bottom-N workspaces by experiments/projects and users by Opik spans / EM activity,
exact from chargeback), and a **Personal vs Service accounts** split (service
accounts from the admin API, with a labeled regex fallback). Each people section
degrades independently: if its inputs are missing, a warning is printed and only
that section is dropped.

**Caveats:**
* **EM "created" is a proxy** — the Comet API has no true EM project-creation timestamp, so EM project creation is approximated as the earliest experiment start time in that project (falling back to the project's `lastUpdated` time if no experiments exist).
* **Workspace/department "created" is also a proxy** — it's the earliest use-case creation timestamp seen in that workspace, across all platforms.
* **MPM requires provisioning** — if the account/workspace has no MPM model-monitoring provisioned, the MPM collector degrades gracefully (an empty MPM section, `collectors.mpm: false`) instead of failing the whole report.

Opik and MPM collection require their optional SDKs; install them with `pip install 'cometx[all]'` if they aren't already available. Platforms whose SDK can't be imported are silently dropped from `--platforms` (a note is printed) so the report still succeeds with the remaining platforms.
* **Chargeback is required** — the whole report is derived from the admin chargeback report; without admin access the command errors out.
* **Workspace "created" is a proxy** — the earliest member `createdAt`, since chargeback has no workspace-creation timestamp. The added-vs-deleted "deleted" series is also a best-effort proxy (all members removed) and typically reads ~0.
* **"Total projects" counts EM projects only** — chargeback's per-workspace `projects[]` covers Experiment Management; Opik projects and MPM aren't represented (Opik appears only as a per-user span count; MPM is absent).

**Examples:**
```
# Full cross-platform report for all workspaces, default 7-day window
# Org-wide report, default 7-day window
cometx admin growth-report

# Just Opik + EM, 30-day window, monthly chart granularity, for two workspaces
cometx admin growth-report --platforms em,opik --window 30d my-workspace another-workspace
# 30-day window, scoped to two workspaces
cometx admin growth-report --window 30d my-workspace another-workspace

# Write to a file without auto-opening
cometx admin growth-report --no-open --output growth.html

# Fast smoke-test run against a single workspace, don't auto-open
cometx admin growth-report --limit 1 --no-open --output growth.html my-workspace
# 30-day activity window and top/bottom-10 leaderboards, excluding personal
# workspaces named like "user-..."
cometx admin growth-report --active-window 30d --leaderboard-top-n 10 \
--exclude-personal --personal-pattern '^user-'
```

#### gpu-report
Expand Down
2 changes: 1 addition & 1 deletion cometx/_version.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,5 @@
# the express permission of Comet ML Inc.
# *******************************************************

version_info = (3, 6, 8)
version_info = (3, 6, 9)
__version__ = ".".join(map(str, version_info))
Loading
Loading