trackio-1234 / __init__.py
abidlabs's picture
abidlabs HF Staff
Upload folder using huggingface_hub
b83f48f verified
import contextvars
import time
import webbrowser
from pathlib import Path
import huggingface_hub
from gradio_client import Client
from httpx import ReadTimeout
from huggingface_hub.errors import RepositoryNotFoundError
from trackio.deploy import deploy_as_space
from trackio.run import Run
from trackio.ui import demo
from trackio.utils import TRACKIO_DIR, TRACKIO_LOGO_PATH, block_except_in_notebook
__version__ = Path(__file__).parent.joinpath("version.txt").read_text().strip()
current_run: contextvars.ContextVar[Run | None] = contextvars.ContextVar(
"current_run", default=None
)
current_project: contextvars.ContextVar[str | None] = contextvars.ContextVar(
"current_project", default=None
)
current_server: contextvars.ContextVar[str | None] = contextvars.ContextVar(
"current_server", default=None
)
config = {}
SPACE_URL = "https://huggingface.co/spaces/{space_id}"
def init(
project: str,
name: str | None = None,
space_id: str | None = None,
dataset_id: str | None = None,
config: dict | None = None,
) -> Run:
"""
Creates a new Trackio project and returns a Run object.
Args:
project: The name of the project (can be an existing project to continue tracking or a new project to start tracking from scratch).
name: The name of the run (if not provided, a default name will be generated).
space_id: If provided, the project will be logged to a Hugging Face Space instead of a local directory. Should be a complete Space name like "username/reponame". If the Space does not exist, it will be created. If the Space already exists, the project will be logged to it.
dataset_id: If provided, a persistent Hugging Face Dataset will be created and the metrics will be synced to it every 5 minutes. Should be a complete Dataset name like "username/datasetname". If the Dataset does not exist, it will be created. If the Dataset already exists, the project will be appended to it.
config: A dictionary of configuration options. Provided for compatibility with wandb.init()
"""
if not current_server.get() and space_id is None:
_, url, _ = demo.launch(
show_api=False, inline=False, quiet=True, prevent_thread_lock=True
)
current_server.set(url)
else:
url = current_server.get()
if current_project.get() is None or current_project.get() != project:
print(f"* Trackio project initialized: {project}")
if space_id is None:
print(f"* Trackio metrics logged to: {TRACKIO_DIR}")
print(
f'\n* View dashboard by running in your terminal: trackio show --project "{project}"'
)
print(f'* or by running in Python: trackio.show(project="{project}")')
else:
create_space_if_not_exists(space_id, dataset_id)
print(
f"* View dashboard by going to: {SPACE_URL.format(space_id=space_id)}"
)
current_project.set(project)
space_or_url = space_id if space_id else url
client = Client(space_or_url, verbose=False)
run = Run(
project=project, client=client, name=name, config=config, dataset_id=dataset_id
)
current_run.set(run)
globals()["config"] = run.config
return run
def create_space_if_not_exists(
space_id: str,
dataset_id: str | None = None,
) -> None:
"""
Creates a new Hugging Face Space if it does not exist.
Args:
space_id: The ID of the Space to create.
dataset_id: The ID of the Dataset to create.
"""
if "/" not in space_id:
raise ValueError(
f"Invalid space ID: {space_id}. Must be in the format: username/reponame."
)
if dataset_id is not None and "/" not in dataset_id:
raise ValueError(
f"Invalid dataset ID: {dataset_id}. Must be in the format: username/datasetname."
)
try:
huggingface_hub.repo_info(space_id, repo_type="space")
print(f"* Found existing space: {SPACE_URL.format(space_id=space_id)}")
return
except RepositoryNotFoundError:
pass
print(f"* Creating new space: {SPACE_URL.format(space_id=space_id)}")
deploy_as_space(space_id, dataset_id)
client = None
for _ in range(30):
try:
client = Client(space_id, verbose=False)
if client:
break
except ReadTimeout:
print("* Space is not yet ready. Waiting 5 seconds...")
time.sleep(5)
except ValueError as e:
print(f"* Space gave error {e}. Trying again in 5 seconds...")
time.sleep(5)
def log(metrics: dict) -> None:
"""
Logs metrics to the current run.
Args:
metrics: A dictionary of metrics to log.
"""
if current_run.get() is None:
raise RuntimeError("Call trackio.init() before log().")
current_run.get().log(metrics)
def finish():
"""
Finishes the current run.
"""
if current_run.get() is None:
raise RuntimeError("Call trackio.init() before finish().")
current_run.get().finish()
def show(project: str | None = None):
"""
Launches the Trackio dashboard.
Args:
project: The name of the project whose runs to show. If not provided, all projects will be shown and the user can select one.
"""
_, url, share_url = demo.launch(
show_api=False,
quiet=True,
inline=False,
prevent_thread_lock=True,
favicon_path=TRACKIO_LOGO_PATH,
allowed_paths=[TRACKIO_LOGO_PATH],
)
base_url = share_url + "/" if share_url else url
dashboard_url = base_url + f"?project={project}" if project else base_url
print(f"* Trackio UI launched at: {dashboard_url}")
webbrowser.open(dashboard_url)
block_except_in_notebook()