Skip to content

Commit 3eec7e5

Browse files
committed
changes
1 parent 6028f83 commit 3eec7e5

4 files changed

Lines changed: 96 additions & 24 deletions

File tree

.cursor/commands/validate-examples.md

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
description: Stress-test the Trackio library via random examples, CLI, and Playwright UI
3-
argument-hint: "[--count 3] [--seed 42] [--jobs 3] [--include-extra-deps-examples] [--include-secret-env-examples] [--space username/space] [--continue-on-failure]"
3+
argument-hint: "[count] [jobs]"
44
---
55

66
Run the Trackio library validator (examples are only the workload; failures are interpreted as possible Trackio regressions):
@@ -17,13 +17,8 @@ Behavior:
1717
- Runs a random subset of `examples/` scripts (default `--count 3`) to exercise logging, imports, and CLI
1818
- Uses isolated `TRACKIO_DIR` per run (one shared DB when `--jobs 1`, separate sandboxes when `--jobs` > 1)
1919
- **Sequential vs parallel:** default is **parallel** (`--jobs 3`). Use **`--jobs N`** to tune worker count; use `--jobs 1` for sequential mode. CLI checks and UI driving stay sequential afterward so ports and Playwright stay stable
20-
- After successful example runs, validates **Trackio CLI** (`list` / `get` with JSON) and the **dashboard** via Playwright (tabs, checkboxes, screenshots)
20+
- After successful example runs, validates **Trackio CLI** (`list` / `get` with JSON) and the **dashboard** via Playwright to ensure that the demos' UI/UX is as expected, as you check on/on different runs, navigate different tabs, and ensure the expected plots and data appear.
2121
- Collects **Trackio-related** signals (tracebacks touching `trackio`, CLI failures, dashboard console/page issues, etc.), **deduplicates** them, and prints a **`=== Trackio library health report ===`** section at the end. Exit code is non-zero if anything was collected or an example run failed (unless you stop early without `--continue-on-failure`)
2222
- Writes `summary.json` under the artifacts directory (includes `trackio_issues` and paths)
2323
- For remote Spaces data, pass **`--space`** to CLI-backed checks as documented in the Trackio CLI
2424

25-
Optional:
26-
27-
- `--continue-on-failure` — run the remaining examples after a failure; CLI/UI run only for examples that completed successfully
28-
- `--include-extra-deps-examples` — include examples that need optional packages (e.g. `datasets` / `transformers`); excluded by default so missing optional deps are not mistaken for Trackio bugs
29-
- `--include-secret-env-examples` — include examples that need secrets in the environment (e.g. `SLACK_WEBHOOK_URL`); excluded by default

scripts/validate_examples.py

Lines changed: 82 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,10 @@ def _progress(message: str) -> None:
5151

5252
REQUIRES_SECRET_ENV_KEYWORDS = ("slack-webhook",)
5353

54+
INTERACTIVE_HOLD_PATTERN = re.compile(
55+
r"time\.sleep\(\s*(?:[1-9][0-9]{2,}|\d+\s*\*\s*\d+)"
56+
)
57+
5458
BENIGN_CONSOLE_ERROR_SNIPPETS = (
5559
"favicon.ico",
5660
"Failed to load resource: the server responded with a status of 404",
@@ -79,6 +83,7 @@ class ValidationResult:
7983
touched_projects: list[str]
8084
run_stdout_path: Path
8185
run_stderr_path: Path
86+
space_id: str | None = None
8287
trackio_issues: list[TrackioIssue] = field(default_factory=list)
8388

8489

@@ -199,10 +204,34 @@ def _example_candidates(
199204
keyword in name for keyword in REQUIRES_SECRET_ENV_KEYWORDS
200205
):
201206
continue
207+
try:
208+
source = path.read_text()
209+
except OSError:
210+
source = ""
211+
if INTERACTIVE_HOLD_PATTERN.search(source):
212+
continue
202213
filtered.append(path)
203214
return filtered
204215

205216

217+
SPACE_URL_PATTERN = re.compile(
218+
r"huggingface\.co/spaces/([A-Za-z0-9][A-Za-z0-9_.-]*)/([A-Za-z0-9][A-Za-z0-9_.-]*)"
219+
)
220+
221+
222+
def extract_space_id_from_output(output: str) -> str | None:
223+
match = SPACE_URL_PATTERN.search(output)
224+
if not match:
225+
return None
226+
return f"{match.group(1)}/{match.group(2)}"
227+
228+
229+
def space_embed_url(space_id: str) -> str:
230+
user, name = space_id.split("/", 1)
231+
sanitized = re.sub(r"[^A-Za-z0-9]+", "-", f"{user}-{name}").strip("-").lower()
232+
return f"https://{sanitized}.hf.space"
233+
234+
206235
def _ensure_serializable_name(name: str) -> str:
207236
return "".join(ch if ch.isalnum() or ch in ("-", "_", ".") else "_" for ch in name)
208237

@@ -281,15 +310,21 @@ def run_example_and_collect_projects(
281310
),
282311
)
283312

284-
after_projects_raw = _run_trackio_json(list_args, env=env, cwd=repo_root)
313+
detected_space_id = extract_space_id_from_output(result.stdout + result.stderr)
314+
effective_space = space or detected_space_id
315+
316+
after_list_args = ["list", "projects"]
317+
if effective_space:
318+
after_list_args.extend(["--space", effective_space])
319+
after_projects_raw = _run_trackio_json(after_list_args, env=env, cwd=repo_root)
285320
after_projects = set(_normalize_list_response(after_projects_raw, "projects"))
286321
new_projects = after_projects - before_projects
287322
touched_projects = set(new_projects)
288323

289324
for project in sorted(after_projects & before_projects):
290325
runs_args = ["list", "runs", "--project", project]
291-
if space:
292-
runs_args.extend(["--space", space])
326+
if effective_space:
327+
runs_args.extend(["--space", effective_space])
293328
after_runs = _run_trackio_json(runs_args, env=env, cwd=repo_root)
294329
after_runs_set = set(_normalize_list_response(after_runs, "runs"))
295330
before_runs_set = before_runs_by_project.get(project, set())
@@ -325,6 +360,7 @@ def run_example_and_collect_projects(
325360
touched_projects=touched_projects_sorted,
326361
run_stdout_path=stdout_path,
327362
run_stderr_path=stderr_path,
363+
space_id=detected_space_id,
328364
trackio_issues=scanned,
329365
),
330366
issues=scanned,
@@ -379,19 +415,28 @@ def validate_ui(
379415
for project in vr.touched_projects:
380416
app = None
381417
page = None
382-
try:
383-
app, _, _, full_url = trackio.show(
384-
project=project, block_thread=False, open_browser=False
418+
if vr.space_id:
419+
full_url = f"{space_embed_url(vr.space_id)}/?project={project}"
420+
_progress(
421+
f" UI check via remote Space for {vr.example_path.name}: "
422+
f"{full_url}"
385423
)
386-
except Exception as e:
387-
ui_issues.append(
388-
TrackioIssue(
389-
kind="ui_launch",
390-
detail=repr(e),
391-
example=vr.example_path.name,
424+
else:
425+
try:
426+
app, _, _, full_url = trackio.show(
427+
project=project,
428+
block_thread=False,
429+
open_browser=False,
392430
)
393-
)
394-
continue
431+
except Exception as e:
432+
ui_issues.append(
433+
TrackioIssue(
434+
kind="ui_launch",
435+
detail=repr(e),
436+
example=vr.example_path.name,
437+
)
438+
)
439+
continue
395440
raw_console_errors: list[str] = []
396441
page_errors: list[str] = []
397442
try:
@@ -432,10 +477,26 @@ def validate_ui(
432477

433478
page.get_by_role("button", name="Metrics", exact=True).click()
434479
page.wait_for_load_state("networkidle")
480+
page.wait_for_timeout(500)
481+
metrics_shot = (
482+
f"{_ensure_serializable_name(vr.example_path.stem)}__"
483+
f"{_ensure_serializable_name(project)}__metrics.png"
484+
)
485+
page.screenshot(
486+
path=str(screenshots_dir / metrics_shot), full_page=True
487+
)
435488
page.get_by_role(
436489
"button", name="Media & Tables", exact=True
437490
).click()
438491
page.wait_for_load_state("networkidle")
492+
page.wait_for_timeout(500)
493+
media_shot = (
494+
f"{_ensure_serializable_name(vr.example_path.stem)}__"
495+
f"{_ensure_serializable_name(project)}__media.png"
496+
)
497+
page.screenshot(
498+
path=str(screenshots_dir / media_shot), full_page=True
499+
)
439500
page.get_by_role(
440501
"button", name="System Metrics", exact=True
441502
).click()
@@ -512,8 +573,14 @@ def validate_cli_for_results(
512573
for r in results:
513574
env = dict(os.environ)
514575
env["TRACKIO_DIR"] = str(r.trackio_dir)
576+
effective_space = space or r.space_id
577+
if r.space_id and not space:
578+
_progress(
579+
f" Using remote space for CLI check of {r.example_path.name}: "
580+
f"{r.space_id}"
581+
)
515582
try:
516-
validate_cli_data(r.touched_projects, env, repo_root, space)
583+
validate_cli_data(r.touched_projects, env, repo_root, effective_space)
517584
except Exception as e:
518585
issues.append(
519586
TrackioIssue(

trackio/__init__.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -390,6 +390,16 @@ def init(
390390
"* Warning: settings is not used. Provided for compatibility with wandb.init(). Please create an issue at: https://github.com/gradio-app/trackio/issues if you need a specific feature implemented."
391391
)
392392

393+
previous_run = context_vars.current_run.get()
394+
if previous_run is not None:
395+
try:
396+
previous_run.finish()
397+
except Exception as e:
398+
_emit_nonfatal_warning(
399+
f"trackio.init() could not finish the previous run '{previous_run.name}': {e}. Continuing with new run."
400+
)
401+
context_vars.current_run.set(None)
402+
393403
bucket_id_was_explicit = bucket_id is not None
394404
space_id, server_url = utils.resolve_space_id_and_server_url(space_id, server_url)
395405
if bucket_id is None and utils.on_spaces():

trackio/frontend/src/pages/Settings.svelte

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,8 @@
6565
{ title: "List projects", cmd: `trackio${sf} list projects` },
6666
{ title: "List runs", cmd: `trackio${sf} list runs --project "${proj}"` },
6767
{ title: "List metrics", cmd: `trackio${sf} list metrics --project "${proj}" --run <run>` },
68-
{ title: "Project summary", cmd: `trackio${sf} summary --project "${proj}"` },
69-
{ title: "Run summary", cmd: `trackio${sf} summary --project "${proj}" --run <run>` },
68+
{ title: "Project summary", cmd: `trackio${sf} get project --project "${proj}"` },
69+
{ title: "Run summary", cmd: `trackio${sf} get run --project "${proj}" --run <run>` },
7070
{ title: "Sync to HF Space", cmd: `trackio sync${sf} --project "${proj}"` },
7171
{ title: "Check sync status", cmd: `trackio status` },
7272
];

0 commit comments

Comments
 (0)