CtrlK
BlogDocsLog inGet started
Tessl Logo

domino-python-sdk

Programmatically interact with Domino using python-domino SDK and REST APIs. Covers authentication, running jobs, managing projects, file operations, model deployment, and automation. Use when automating Domino workflows, integrating with CI/CD, or building custom tooling around Domino.

SKILL.md
Quality
Evals
Security

Domino Python SDK Skill

Description

This skill helps users work with the Domino Python SDK (python-domino) and REST APIs to programmatically interact with Domino.

Activation

Activate this skill when users want to:

  • Use the Domino Python SDK
  • Make API calls to Domino
  • Automate Domino workflows
  • Integrate Domino with external systems
  • Query Domino programmatically

Overview

Domino provides two main programmatic interfaces:

  • python-domino: Python SDK for common operations
  • REST API: Full HTTP API for all Domino features

Installation

python-domino

# Install from PyPI
pip install dominodatalab

# Or install with extras
pip install "dominodatalab[data]"

In Domino Environment

Add to requirements.txt:

dominodatalab>=1.4.0

Or Dockerfile:

RUN pip install dominodatalab

Authentication

Canonical guide: https://docs.domino.ai/cloud/reference/api/domino-api-authentication

Do not use API keys (X-Domino-Api-Key, DOMINO_USER_API_KEY, api_key=). Use PAT or service account tokens only when calling from outside a run.

In-run (workspace, job, app backend)

Domino injects DOMINO_USER_HOST / DOMINO_API_HOST (same base; prefer DOMINO_USER_HOST). When JWT credential propagation is enabled, DOMINO_API_PROXY is the forwarded platform API base (not the same as http://localhost:8899/access-token).

PatternWhenCode
API proxy (preferred)DOMINO_API_PROXY is set (Domino 5.4.0+ in runs with JWT credential propagation configured)Call {DOMINO_API_PROXY}{path} with no Authorization header. The JWT sidecar adds the starting user access JWT on the forwarded request.
Access token + platform hostOlder deployments, or you intentionally call DOMINO_USER_HOST / DOMINO_API_HOST instead of the proxy URLFetch a short-lived JWT, then Bearer on the platform base.

API proxy (preferred on 5.4.0+):

import os
import requests

base_url = os.environ["DOMINO_API_PROXY"].rstrip("/")
headers = {}

response = requests.get(f"{base_url}/v4/users/self")
curl "$DOMINO_API_PROXY/v4/users/self"

The proxy is not guaranteed on every deployment or run type. If DOMINO_API_PROXY is missing, use the access-token pattern or PAT from outside the cluster.

Access token + DOMINO_USER_HOST (legacy-friendly in-run): use the In-run setup block below; it covers both proxy and access-token paths.

Before Domino 5.4.0: JWT file propagation (DOMINO_TOKEN_FILE) was used before the API proxy; legacy behavior may still exist if admins enable EnableLegacyJwtTooling. Prefer migrating to the proxy pattern on supported versions.

Outside a run (laptop, CI, cron outside Domino)

Your code is not executing inside a Domino workspace, job, or app container. Domino does not inject DOMINO_API_PROXY, DOMINO_USER_HOST, or an access-token sidecar. You must supply both:

  1. Base URL — the deployment URL users open in the browser (HTTPS), for example https://yourcompany.engineering.domino.tech. Not http://127.0.0.1:8763 and not values copied from an in-run environment.
  2. Credential — Authorization: Bearer with a token you store securely (secret manager, CI variable, not committed to git):
    • Personal Access Token (PAT) when the automation acts as you. Create under Account settings or POST /api/pat/v1/tokens while already authenticated.
    • Service account token when a pipeline or integration runs without a human user. An admin provisions the service account and token.
import requests

deployment_url = "https://yourcompany.engineering.domino.tech"
pat = "..."  # from your secret store; never hardcode in shared repos

response = requests.get(
    f"{deployment_url.rstrip('/')}/v4/users/self",
    headers={"Authorization": f"Bearer {pat}"},
)

See https://docs.domino.ai/cloud/reference/api/domino-api-authentication .

In-run setup block (for examples in this skill)

Use inside a workspace, job, or app only:

import os
import requests

if os.environ.get("DOMINO_API_PROXY"):
    base_url = os.environ["DOMINO_API_PROXY"].rstrip("/")
    headers = {}
else:
    base_url = (os.environ.get("DOMINO_USER_HOST") or os.environ.get("DOMINO_API_HOST") or "").rstrip("/")
    token = requests.get("http://localhost:8899/access-token").text.strip()
    headers = {"Authorization": f"Bearer {token}"}

python-domino inside Domino

from domino import Domino

domino = Domino("owner/project-name")

Configure the SDK with host + Bearer token per the product auth page. Never pass api_key=.

Common Operations

Projects

from domino import Domino

domino = Domino()

# Create project
project = domino.project_create(
    project_name="my-new-project",
    owner_name="username"
)

# Get project info
info = domino.project_info()
print(f"Project: {info['name']}")
print(f"ID: {info['id']}")

Jobs (Runs)

# Start a job
run = domino.runs_start(
    command="python train.py --epochs 100",
    hardware_tier_name="medium",
    environment_id="env-id"
)
print(f"Run ID: {run['runId']}")

# Start job with different commit
run = domino.runs_start(
    command="python train.py",
    commit_id="abc123"
)

# Check status
status = domino.runs_status(run['runId'])
print(f"Status: {status['status']}")

# Wait for completion
domino.runs_wait(run['runId'])

# Get logs
logs = domino.runs_get_logs(run['runId'])
print(logs)

# Stop a run
domino.runs_stop(run['runId'])

Workspaces

# Start workspace
workspace = domino.workspace_start(
    hardware_tier_name="medium",
    environment_id="env-id",
    workspace_type="JupyterLab"
)
print(f"Workspace ID: {workspace['workspaceId']}")

# Stop workspace
domino.workspace_stop(workspace['workspaceId'])

Files

# Upload file
domino.files_upload(
    path="local/file.csv",
    dest_path="/mnt/code/data/"
)

# Download file
domino.files_download(
    path="/mnt/code/results/output.csv",
    dest_path="local/output.csv"
)

# List files
files = domino.files_list("/mnt/code/")
for f in files:
    print(f['path'])

Datasets

# Create dataset
dataset = domino.datasets_create(
    name="training-data",
    description="Training dataset"
)

# List datasets
datasets = domino.datasets_list()

# Create snapshot
snapshot = domino.datasets_snapshot(
    dataset_name="training-data",
    tag="v1.0"
)

Environments

# List environments
environments = domino.environments_list()
for env in environments:
    print(f"{env['name']}: {env['id']}")

# Get environment details
env = domino.environment_get("env-id")

Model APIs

# Publish model
model = domino.model_publish(
    file="model.py",
    function="predict",
    environment_id="env-id",
    name="my-classifier",
    description="Classification model"
)
print(f"Model ID: {model['id']}")

# List models
models = domino.models_list()

# Get model info
model_info = domino.model_get("model-id")

REST API

Use the Authentication setup (base_url, headers) for examples below.

response = requests.get(f"{base_url}/api/projects/beta/projects", headers=headers or None)
projects = response.json()

Common Endpoints

EndpointMethodDescription
/v4/projectsGETList projects
/v4/projects/{id}/runsPOSTStart a run
/v4/projects/{id}/runs/{runId}GETGet run status
/v4/projects/{id}/filesGETList files
/v4/gateway/runs/{runId}/logsGETGet run logs
/v4/modelsGETList models
/v4/models/{id}/latest/modelPOSTCall model

Domino Data API

Separate SDK for data access:

from domino_data.data_sources import DataSourceClient

# Initialize client
client = DataSourceClient()

# List data sources
sources = client.list_data_sources()

# Query data source
df = client.get_datasource("my-datasource").query(
    "SELECT * FROM customers WHERE region = 'US'"
)

Automation Examples

CI/CD Integration

# trigger_training.py - Call from CI/CD pipeline
from domino import Domino
import sys

domino = Domino("team/ml-project")

# Start training job
run = domino.runs_start(
    command="python train.py",
    hardware_tier_name="gpu-large"
)

# Wait for completion
result = domino.runs_wait(run['runId'])

if result['status'] != 'Succeeded':
    print(f"Training failed: {result['status']}")
    sys.exit(1)

print("Training completed successfully!")

Batch Job Scheduler

# Run multiple experiments
from domino import Domino
import itertools

domino = Domino("team/experiments")

# Parameter grid
params = {
    "learning_rate": [0.01, 0.001, 0.0001],
    "batch_size": [32, 64, 128]
}

# Generate combinations
combinations = list(itertools.product(*params.values()))
param_names = list(params.keys())

# Submit all experiments
runs = []
for combo in combinations:
    param_str = " ".join(
        f"--{name}={value}"
        for name, value in zip(param_names, combo)
    )
    run = domino.runs_start(
        command=f"python experiment.py {param_str}",
        hardware_tier_name="gpu-small"
    )
    runs.append(run['runId'])
    print(f"Started run {run['runId']} with {param_str}")

# Wait for all to complete
for run_id in runs:
    result = domino.runs_wait(run_id)
    print(f"Run {run_id}: {result['status']}")

Model Deployment Pipeline

from domino import Domino

domino = Domino("team/model-deployment")

# 1. Train model
train_run = domino.runs_start(command="python train.py")
domino.runs_wait(train_run['runId'])

# 2. Evaluate model
eval_run = domino.runs_start(command="python evaluate.py")
domino.runs_wait(eval_run['runId'])

# 3. Deploy if evaluation passes
# (Check evaluation results first)
model = domino.model_publish(
    file="serve.py",
    function="predict",
    name="production-model"
)

print(f"Model deployed: {model['id']}")

Error Handling

from domino import Domino
from domino.exceptions import DominoException

try:
    domino = Domino("team/project")
    run = domino.runs_start(command="python train.py")
except DominoException as e:
    print(f"Domino error: {e}")
except Exception as e:
    print(f"Unexpected error: {e}")

Best Practices

1. Follow Authentication

Proxy without a header when DOMINO_API_PROXY is set; otherwise access-token + platform host; PAT/SA only outside a run.

2. Handle Rate Limits

import time
from domino.exceptions import DominoException

def api_call_with_retry(func, max_retries=3):
    for attempt in range(max_retries):
        try:
            return func()
        except DominoException as e:
            if "rate limit" in str(e).lower():
                time.sleep(2 ** attempt)
            else:
                raise
    raise Exception("Max retries exceeded")

3. Log API Calls

import logging

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

def start_run(command):
    logger.info(f"Starting run: {command}")
    run = domino.runs_start(command=command)
    logger.info(f"Run ID: {run['runId']}")
    return run

Detailed API Reference

For comprehensive REST API documentation, see these specialized guides:

GuideDescription
API-PROJECTS.mdProjects, collaborators, Git repos, goals
API-JOBS.mdJobs, scheduled jobs, logs, tags
API-DATASETS.mdDatasets, snapshots, tags, grants
API-MODELS.mdModel APIs, deployments, registry
API-MODEL-SERVING.mdLifecycle, v1/v2 registry split, invoke vs management
API-ENVIRONMENTS.mdEnvironments, revisions, Dockerfile
API-APPS.mdApps endpoint catalog (see apps/API-APPS.md for v1 automation)
API-ADMIN.mdUsers, orgs, hardware tiers, data sources
API-REFERENCE.mdComplete endpoint reference

Documentation Reference

OpenAPI and route discovery: API-SPECS.md.

Product docs:

Repository
dominodatalab/domino-claude-plugin
Last updated
First committed

Is this your skill?

If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.