Skip to content

Commit 27a50a3

Browse files
Add configurable custom frontends for Trackio (#531)
Co-authored-by: gradio-pr-bot <gradio-pr-bot@users.noreply.github.com>
1 parent 08bc5eb commit 27a50a3

40 files changed

Lines changed: 4786 additions & 70 deletions

.changeset/little-cats-bet.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"trackio": minor
3+
---
4+
5+
feat:Add configurable custom frontends for Trackio

README.md

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,32 @@ import trackio
146146
trackio.show(project="my-project")
147147
```
148148

149+
You can also point Trackio at a custom static frontend directory:
150+
151+
```bash
152+
trackio show --frontend ./my-trackio-frontend
153+
```
154+
155+
```py
156+
import trackio
157+
158+
trackio.show(frontend_dir="./my-trackio-frontend")
159+
```
160+
161+
The directory only needs an `index.html` file. Trackio keeps serving the same backend API under `/api/*`, so you can replace the UI without forking the backend. If the directory is missing or invalid, Trackio falls back to a minimal starter template.
162+
163+
To make a custom frontend apply everywhere by default:
164+
165+
```bash
166+
trackio config set frontend ./my-trackio-frontend
167+
```
168+
169+
Reset it with:
170+
171+
```bash
172+
trackio config unset frontend
173+
```
174+
149175
## Deploying to Hugging Face Spaces
150176

151177
When calling `trackio.init()`, by default the service will run locally and store project data on the local machine.
@@ -183,10 +209,14 @@ If you've been tracking experiments locally and want to move them to Hugging Fac
183209
```py
184210
import trackio
185211

186-
trackio.sync(project="my-project", space_id="username/space_id")
212+
trackio.sync(
213+
project="my-project",
214+
space_id="username/space_id",
215+
frontend_dir="./my-trackio-frontend",
216+
)
187217
```
188218

189-
This uploads your local project database to a new or existing Space. The Space will display all your logged experiments and metrics.
219+
This uploads your local project database to a new or existing Space. The Space will display all your logged experiments and metrics, and if a custom frontend is configured or passed explicitly it will be deployed there too.
190220

191221
**Example workflow:**
192222

@@ -199,7 +229,11 @@ trackio.log({"loss": 0.5})
199229
trackio.finish()
200230

201231
# Later, sync to Spaces
202-
trackio.sync(project="my-project", space_id="username/my-experiments")
232+
trackio.sync(
233+
project="my-project",
234+
space_id="username/my-experiments",
235+
frontend_dir="./my-trackio-frontend",
236+
)
203237
```
204238

205239
## Embedding a Trackio Dashboard

docs/source/environment_variables.md

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,18 @@ export TRACKIO_WRITE_TOKEN="YOUR_TOKEN"
3131

3232
The dashboard **write token** for a self-hosted Trackio server (same value as the `write_token` query parameter in the write-access URL). Use this when `TRACKIO_SERVER_URL` or `server_url` is a base URL without query parameters. The client sends this token on each request (for example as the `X-Trackio-Write-Token` header) so metric ingestion and uploads are authenticated when not running on Hugging Face Spaces.
3333

34+
### `TRACKIO_FRONTEND_DIR`
35+
36+
Path to a custom static frontend directory for Trackio. The directory must contain `index.html`.
37+
38+
When set, Trackio uses that frontend for `trackio.show()` and for deploy flows such as `trackio.sync()` and `trackio.freeze()`, unless an explicit `frontend_dir` / `--frontend` argument is passed.
39+
40+
```bash
41+
export TRACKIO_FRONTEND_DIR="/path/to/my-trackio-frontend"
42+
```
43+
44+
If the configured directory is invalid, Trackio ignores it and falls back to the built-in frontend selection logic. The automatic starter-template copy behavior only applies when an explicit `frontend_dir` / `--frontend` argument points to a missing or empty directory.
45+
3446
### `TRACKIO_LOGO_LIGHT_URL` and `TRACKIO_LOGO_DARK_URL`
3547

3648
Customize the logos displayed in the Trackio dashboard for light and dark themes. You can provide URLs to custom logos. Note that both environment variables should be supplied; otherwise, the Trackio default will be used for any variable that is not provided.
@@ -164,5 +176,3 @@ export GRADIO_MCP_SERVER="True"
164176
165177
166178
See [this more comprehensive list](https://www.gradio.app/guides/environment-variables) of environment variables used by Gradio.
167-
168-

docs/source/launch.md

Lines changed: 61 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -46,15 +46,56 @@ trackio.show(project="my-project")
4646
</hfoption>
4747
</hfoptions>
4848

49-
## Changing the Theme
50-
51-
You can change the theme of the dashboard by providing an optional `theme` argument.
49+
## Using a Custom Frontend
50+
51+
You can replace the bundled dashboard with your own static frontend directory. The directory only needs an `index.html` file; your frontend can call the existing Trackio API under `/api/*`.
52+
53+
The intended workflow is:
54+
55+
1. Run `trackio show --frontend ./my-trackio-frontend`.
56+
2. Ask your LLM to edit the files in that directory.
57+
3. Keep the browser open while Trackio live reloads the frontend as those files change.
58+
59+
If the directory passed to `--frontend` does not exist, or exists but is empty, Trackio copies in the starter frontend automatically, prints that it did so, and then serves that directory. The starter is a complete plain-HTML/CSS/JS template: it calls the Trackio API, loads projects and runs, fetches metric values, and draws simple charts that you can replace with your own UI.
60+
61+
The currently available HTTP endpoints are:
62+
63+
- `POST /api/get_run_mutation_status`
64+
- `POST /api/upload_db_to_space`
65+
- `POST /api/bulk_upload_media`
66+
- `POST /api/log`
67+
- `POST /api/bulk_log`
68+
- `POST /api/bulk_log_system`
69+
- `POST /api/bulk_alert`
70+
- `POST /api/get_alerts`
71+
- `POST /api/get_metric_values`
72+
- `POST /api/get_runs_for_project`
73+
- `POST /api/get_metrics_for_run`
74+
- `POST /api/get_all_projects`
75+
- `POST /api/get_project_summary`
76+
- `POST /api/get_run_summary`
77+
- `POST /api/get_system_metrics_for_run`
78+
- `POST /api/get_system_logs`
79+
- `POST /api/get_system_logs_batch`
80+
- `POST /api/get_snapshot`
81+
- `POST /api/get_logs`
82+
- `POST /api/get_logs_batch`
83+
- `POST /api/get_traces`
84+
- `POST /api/query_project`
85+
- `POST /api/get_settings`
86+
- `POST /api/get_project_files`
87+
- `POST /api/delete_run`
88+
- `POST /api/rename_run`
89+
- `POST /api/force_sync`
90+
- `POST /api/upload` for multipart file uploads used by media and file-related flows
91+
92+
For reading stored files returned by the API, Trackio also serves `GET /file?path=...`.
5293

5394
<hfoptions id="language">
5495
<hfoption id="Shell">
5596

5697
```sh
57-
trackio show --theme "soft"
98+
trackio show --frontend ./my-trackio-frontend
5899
```
59100

60101
</hfoption>
@@ -63,13 +104,27 @@ trackio show --theme "soft"
63104
```py
64105
import trackio
65106

66-
trackio.show(theme="soft")
107+
trackio.show(frontend_dir="./my-trackio-frontend")
67108
```
68109

69110
</hfoption>
70111
</hfoptions>
71112

72-
To see the available themes, check out the [themes gallery](https://huggingface.co/spaces/gradio/theme-gallery).
113+
If the provided frontend directory is non-empty but invalid, Trackio falls back to the shipped starter template.
114+
115+
## Setting a Persistent Default Frontend
116+
117+
If you want the same custom frontend to be used by `trackio show`, `trackio sync`, and deploy flows by default, save it in Trackio's persistent config:
118+
119+
```sh
120+
trackio config set frontend ./my-trackio-frontend
121+
```
122+
123+
Reset it with:
124+
125+
```sh
126+
trackio config unset frontend
127+
```
73128

74129
## Customizing Plot Colors
75130

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# Custom Frontend Examples
2+
3+
These folders are not used by Trackio at runtime.
4+
5+
They exist so the custom frontend feature can ship with a few visually distinct examples
6+
that are easy to screenshot, copy, and remix.
7+
8+
Each example includes:
9+
10+
- `frontend/`: a complete static frontend directory that can be passed to `trackio show --frontend`
11+
- `screenshot.png`: a screenshot for docs, PRs, and social posts
12+
13+
Examples:
14+
15+
- `editorial`
16+
- `signal`
17+
- `starter`
18+
- `sunrise`
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import { mountTheme } from "./shared-theme.js";
2+
3+
mountTheme({
4+
title: document.querySelector("#title"),
5+
projectSelect: document.querySelector("#project-select"),
6+
runSelect: document.querySelector("#run-select"),
7+
metricsEl: document.querySelector("#metrics"),
8+
metricsSubtitle: document.querySelector("#metrics-subtitle"),
9+
projectSummary: document.querySelector("#project-summary"),
10+
runsCount: document.querySelector("#runs-count"),
11+
metricsCount: document.querySelector("#metrics-count"),
12+
selectedRunName: document.querySelector("#selected-run-name"),
13+
selectedRunMeta: document.querySelector("#selected-run-meta"),
14+
});
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
<!doctype html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="utf-8" />
5+
<meta name="viewport" content="width=device-width, initial-scale=1" />
6+
<title>Editorial</title>
7+
<link rel="stylesheet" href="./styles.css" />
8+
</head>
9+
<body>
10+
<main class="shell">
11+
<aside class="sidebar">
12+
<img
13+
src="/static/trackio/trackio_logo_type_light_transparent.png"
14+
alt="Trackio"
15+
class="editorial-logo"
16+
/>
17+
<p class="kicker">Editorial</p>
18+
<h1 id="title">Loading</h1>
19+
<p id="project-summary" class="sidebar-note">Choose a project and run.</p>
20+
21+
<section class="control-block">
22+
<label class="control-label" for="project-select">Project</label>
23+
<select id="project-select" class="selector"></select>
24+
</section>
25+
26+
<section class="control-block">
27+
<label class="control-label" for="run-select">Run</label>
28+
<select id="run-select" class="selector"></select>
29+
</section>
30+
31+
<section class="stat-grid">
32+
<div class="stat-card">
33+
<span class="stat-label">Runs</span>
34+
<strong id="runs-count">0</strong>
35+
</div>
36+
<div class="stat-card">
37+
<span class="stat-label">Metrics</span>
38+
<strong id="metrics-count">0</strong>
39+
</div>
40+
</section>
41+
</aside>
42+
43+
<section class="content">
44+
<div class="panel metrics-panel">
45+
<div class="panel-head">
46+
<div>
47+
<h2>Metrics</h2>
48+
<p id="metrics-subtitle" class="section-note">Metric plots for the selected run.</p>
49+
</div>
50+
<div class="panel-meta">
51+
<span id="selected-run-name">Loading run</span>
52+
<span id="selected-run-meta">Waiting for Trackio data.</span>
53+
</div>
54+
</div>
55+
<div id="metrics"></div>
56+
</div>
57+
</section>
58+
</main>
59+
<script type="module" src="./app.js"></script>
60+
</body>
61+
</html>

0 commit comments

Comments
 (0)