Skip to content

Commit 073715d

Browse files
Improvements to trackio.sync() (#358)
Co-authored-by: gradio-pr-bot <gradio-pr-bot@users.noreply.github.com>
1 parent e2b381e commit 073715d

7 files changed

Lines changed: 60 additions & 10 deletions

File tree

.changeset/open-plants-shop.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:Improvements to `trackio.sync()`

trackio/__init__.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,9 +163,12 @@ def init(
163163
favicon_path=TRACKIO_LOGO_DIR / "trackio_logo_light.png",
164164
allowed_paths=[TRACKIO_LOGO_DIR, TRACKIO_DIR],
165165
)
166+
context_vars.current_space_id.set(None)
166167
else:
167168
url = space_id
168169
share_url = None
170+
context_vars.current_space_id.set(space_id)
171+
169172
context_vars.current_server.set(url)
170173
context_vars.current_share_server.set(share_url)
171174
if (

trackio/context_vars.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@
1313
current_server: contextvars.ContextVar[str | None] = contextvars.ContextVar(
1414
"current_server", default=None
1515
)
16+
current_space_id: contextvars.ContextVar[str | None] = contextvars.ContextVar(
17+
"current_space_id", default=None
18+
)
1619
current_share_server: contextvars.ContextVar[str | None] = contextvars.ContextVar(
1720
"current_share_server", default=None
1821
)

trackio/deploy.py

Lines changed: 36 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import importlib.metadata
22
import io
33
import os
4+
import threading
45
import time
56
from importlib.resources import files
67
from pathlib import Path
@@ -13,7 +14,7 @@
1314

1415
import trackio
1516
from trackio.sqlite_storage import SQLiteStorage
16-
from trackio.utils import preprocess_space_and_dataset_ids
17+
from trackio.utils import get_or_create_project_hash, preprocess_space_and_dataset_ids
1718

1819
SPACE_HOST_URL = "https://{user_name}-{space_name}.hf.space/"
1920
SPACE_URL = "https://huggingface.co/spaces/{space_id}"
@@ -294,25 +295,52 @@ def upload_db_to_space(project: str, space_id: str, force: bool = False) -> None
294295

295296

296297
def sync(
297-
project: str, space_id: str, private: bool | None = None, force: bool = False
298-
) -> None:
298+
project: str,
299+
space_id: str | None = None,
300+
private: bool | None = None,
301+
force: bool = False,
302+
run_in_background: bool = False,
303+
) -> str:
299304
"""
300305
Syncs a local Trackio project's database to a Hugging Face Space.
301306
If the Space does not exist, it will be created.
302307
303308
Args:
304309
project (`str`): The name of the project to upload.
305-
space_id (`str`): The ID of the Space to upload to (e.g., `"username/space_id"`).
310+
space_id (`str`, *optional*): The ID of the Space to upload to (e.g., `"username/space_id"`).
311+
If not provided, a random space_id (e.g. "username/project-2ac3z2aA") will be used.
306312
private (`bool`, *optional*):
307313
Whether to make the Space private. If None (default), the repo will be
308314
public unless the organization's default is private. This value is ignored
309315
if the repo already exists.
310316
force (`bool`, *optional*, defaults to `False`):
311317
If `True`, overwrite the existing database without prompting for confirmation.
312318
If `False`, prompt the user before overwriting an existing database.
319+
run_in_background (`bool`, *optional*, defaults to `False`):
320+
If `True`, the Space creation and database upload will be run in a background thread.
321+
If `False`, all the steps will be run synchronously.
322+
Returns:
323+
`str`: The Space ID of the synced project.
313324
"""
325+
if space_id is None:
326+
space_id = f"{project}-{get_or_create_project_hash(project)}"
314327
space_id, _ = preprocess_space_and_dataset_ids(space_id, None)
315-
create_space_if_not_exists(space_id, private=private)
316-
wait_until_space_exists(space_id)
317-
upload_db_to_space(project, space_id, force=force)
318-
print(f"Synced successfully to space: {SPACE_URL.format(space_id=space_id)}")
328+
329+
def space_creation_and_upload(
330+
space_id: str, private: bool | None = None, force: bool = False
331+
):
332+
print(
333+
f"* Syncing local Trackio project to: {SPACE_URL.format(space_id=space_id)} (please wait...)"
334+
)
335+
create_space_if_not_exists(space_id, private=private)
336+
wait_until_space_exists(space_id)
337+
upload_db_to_space(project, space_id, force=force)
338+
print(f"* Synced successfully to space: {SPACE_URL.format(space_id=space_id)}")
339+
340+
if run_in_background:
341+
threading.Thread(
342+
target=space_creation_and_upload, args=(space_id, private, force)
343+
).start()
344+
else:
345+
space_creation_and_upload(space_id, private, force)
346+
return space_id

trackio/ui/main.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
from trackio.ui.components.colored_checkbox import ColoredCheckboxGroup
2626
from trackio.ui.files import files_page
2727
from trackio.ui.helpers.run_selection import RunSelection
28-
from trackio.ui.media import media_page
28+
from trackio.ui.media_page import media_page
2929
from trackio.ui.run_detail import run_detail_page
3030
from trackio.ui.runs import run_page
3131
except ImportError:
@@ -42,7 +42,7 @@
4242
from ui.components.colored_checkbox import ColoredCheckboxGroup
4343
from ui.files import files_page
4444
from ui.helpers.run_selection import RunSelection
45-
from ui.media import media_page
45+
from ui.media_page import media_page
4646
from ui.run_detail import run_detail_page
4747
from ui.runs import run_page
4848

trackio/utils.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import math
22
import os
33
import re
4+
import secrets
45
import time
56
from datetime import datetime, timezone
67
from functools import lru_cache
@@ -140,6 +141,16 @@ def _get_trackio_dir() -> Path:
140141
FILES_DIR = TRACKIO_DIR / "files"
141142

142143

144+
def get_or_create_project_hash(project: str) -> str:
145+
hash_path = TRACKIO_DIR / f"{project}.hash"
146+
if hash_path.exists():
147+
return hash_path.read_text().strip()
148+
hash_value = secrets.token_urlsafe(8)
149+
TRACKIO_DIR.mkdir(parents=True, exist_ok=True)
150+
hash_path.write_text(hash_value)
151+
return hash_value
152+
153+
143154
def generate_readable_name(used_names: list[str], space_id: str | None = None) -> str:
144155
"""
145156
Generates a random, readable name like "dainty-sunset-0".

0 commit comments

Comments
 (0)