Build custom templates with pre-configured environments, dependencies, and settings. Templates allow you to create reusable sandbox configurations.
Prerequisites
Before you begin, make sure you have:
- HopX API key - Get one from console.hopx.dev or see [API key Management](/API key)
- Understanding of templates - Familiarity with Listing Templates is helpful
- Base image or template - Decide on a base image (Python, Node.js, Ubuntu, etc.)
- Dependencies list - Know what packages or tools you want pre-installed
Overview
Building templates enables you to:
- Pre-install packages and dependencies
- Configure environment variables
- Set up working directories and users
- Create reusable sandbox configurations
- Optimize sandbox creation time
Template building is an async operation that can take several minutes. The build process includes uploading files, executing build steps, and waiting for template activation.
Basic Template Building
Create a simple template from a base image:
from hopx_ai.template import Template, BuildOptions
import os
# Create template from base image
template = Template()
template.from_python_image("3.11-slim")
# Add build steps
template.run_cmd("pip install numpy pandas matplotlib")
# Build template
options = BuildOptions(
name="my-python-template",
api_key=os.getenv("HOPX_API_KEY"),
cpu=2,
memory=2048,
disk_gb=10,
context_path=os.getcwd() # Required: working directory for file operations
)
result = await Template.build(template, options)
print(f"Template built: {result.template_id}")
print(f"Build ID: {result.build_id}")
// Note: JavaScript SDK template building may have different API
// This is a conceptual example based on Python SDK patterns
import { Template, BuildOptions } from '@hopx-ai/sdk';
// Create template from base image
const template = new Template('python:3.11-slim');
// Add build steps
template.runCmd('pip install numpy pandas matplotlib');
// Build template
const options = new BuildOptions({
name: 'my-python-template',
apiKey: process.env.HOPX_API_KEY,
cpu: 2,
memory: 2048,
diskGb: 10
});
const result = await Template.build(template, options);
console.log(`Template built: ${result.templateId}`);
Using Base Image Helpers
Use convenient base image helpers:
from hopx_ai.template import Template, BuildOptions
import os
# From Ubuntu
template = Template().from_ubuntu_image("22.04")
template.apt_install("curl", "git", "vim")
# From Python
template = Template().from_python_image("3.11")
template.pip_install("numpy", "pandas")
# From Node.js
template = Template().from_node_image("20")
template.npm_install("typescript", "tsx")
# Build
options = BuildOptions(
name="my-template",
api_key=os.getenv("HOPX_API_KEY"),
context_path=os.getcwd()
)
result = await Template.build(template, options)
// Conceptual example
import { Template, BuildOptions } from '@hopx-ai/sdk';
// From Ubuntu
const template = new Template().fromUbuntuImage('22.04');
template.aptInstall('curl', 'git', 'vim');
// From Python
const template2 = new Template().fromPythonImage('3.11');
template2.pipInstall('numpy', 'pandas');
// From Node.js
const template3 = new Template().fromNodeImage('20');
template3.npmInstall('typescript', 'tsx');
Complete Template Example
Build a complete template with multiple steps:
from hopx_ai.template import Template, BuildOptions
from hopx_ai.template.ready_checks import wait_for_port
import os
# Create template
template = Template()
template.from_python_image("3.11-slim")
# Install system packages
template.apt_install("curl", "git", "build-essential")
# Set working directory
template.set_workdir("/app")
# Install Python packages
template.pip_install("flask", "gunicorn", "redis")
# Set environment variables
template.set_env("FLASK_ENV", "production")
template.set_env("PORT", "8000")
# Copy files (requires file upload)
# template.copy("/local/path", "/app", options=CopyOptions(owner="appuser"))
# Set start command and ready check
template.set_start_cmd(
"gunicorn -w 4 -b 0.0.0.0:8000 app:app",
ready=wait_for_port(8000, timeout=30000)
)
# Build template
options = BuildOptions(
name="flask-app-template",
api_key=os.getenv("HOPX_API_KEY"),
cpu=2,
memory=2048,
disk_gb=10,
context_path=os.getcwd() # Required for file operations
)
result = await Template.build(template, options)
print(f"✅ Template built: {result.template_id}")
print(f" Build ID: {result.build_id}")
print(f" Duration: {result.duration}s")
// Conceptual example
import { Template, BuildOptions, waitForPort } from '@hopx-ai/sdk';
const template = new Template('python:3.11-slim');
// Install system packages
template.aptInstall('curl', 'git', 'build-essential');
// Set working directory
template.setWorkdir('/app');
// Install Python packages
template.pipInstall('flask', 'gunicorn', 'redis');
// Set environment variables
template.setEnv('FLASK_ENV', 'production');
template.setEnv('PORT', '8000');
// Set start command and ready check
template.setStartCmd(
'gunicorn -w 4 -b 0.0.0.0:8000 app:app',
waitForPort(8000, { timeout: 30000 })
);
// Build template
const options = new BuildOptions({
name: 'flask-app-template',
apiKey: process.env.HOPX_API_KEY,
cpu: 2,
memory: 2048,
diskGb: 10
});
const result = await Template.build(template, options);
console.log(`✅ Template built: ${result.templateId}`);
Build Options
Configure build options:
from hopx_ai.template import BuildOptions
import os
options = BuildOptions(
name="my-template", # Required: Template name
api_key=os.getenv("HOPX_API_KEY"), # Required: API key
cpu=2, # CPU cores (default: 2)
memory=2048, # Memory in MB (default: 2048)
disk_gb=10, # Disk in GB (default: 10)
context_path=os.getcwd(), # Required: Working directory for file operations
skip_cache=False, # Skip build cache (default: False)
update=False, # Update existing template (default: False)
template_activation_timeout=2700 # Max wait for activation in seconds (default: 2700)
)
# With progress callbacks
def on_progress(progress: int):
print(f"Build progress: {progress}%")
def on_log(log_entry: dict):
print(f"[{log_entry['level']}] {log_entry['message']}")
options.on_progress = on_progress
options.on_log = on_log
// Conceptual example
const options = new BuildOptions({
name: 'my-template', // Required: Template name
apiKey: process.env.HOPX_API_KEY, // Required: API key
cpu: 2, // CPU cores (default: 2)
memory: 2048, // Memory in MB (default: 2048)
diskGb: 10, // Disk in GB (default: 10)
skipCache: false, // Skip build cache (default: false)
update: false, // Update existing template (default: false)
templateActivationTimeout: 2700, // Max wait for activation in seconds
onProgress: (progress) => {
console.log(`Build progress: ${progress}%`);
},
onLog: (logEntry) => {
console.log(`[${logEntry.level}] ${logEntry.message}`);
}
});
Build Result and Logs
Access build results and logs:
from hopx_ai.template import Template, BuildOptions
import os
# Build template
template = Template()
template.from_python_image("3.11-slim")
template.pip_install("numpy")
options = BuildOptions(
name="test-template",
api_key=os.getenv("HOPX_API_KEY"),
context_path=os.getcwd()
)
result = await Template.build(template, options)
# Access build information
print(f"Build ID: {result.build_id}")
print(f"Template ID: {result.template_id}")
print(f"Duration: {result.duration}s")
# Get build logs
logs = await result.get_logs()
print(f"Logs:\n{logs.logs}")
# Poll for new logs
if not logs.complete:
new_logs = await result.get_logs(offset=logs.offset)
print(f"New logs:\n{new_logs.logs}")
// Conceptual example
const result = await Template.build(template, options);
// Access build information
console.log(`Build ID: ${result.buildId}`);
console.log(`Template ID: ${result.templateId}`);
console.log(`Duration: ${result.duration}s`);
// Get build logs
const logs = await result.getLogs();
console.log(`Logs:\n${logs.logs}`);
// Poll for new logs
if (!logs.complete) {
const newLogs = await result.getLogs({ offset: logs.offset });
console.log(`New logs:\n${newLogs.logs}`);
}
Best Practices
1. Start with Base Images
Use base image helpers (from_python_image, from_node_image) for common environments.
2. Chain Operations
Use fluent API to chain operations for readable template definitions.
3. Set Resources Appropriately
Configure CPU, memory, and disk based on your application needs.
4. Use Ready Checks
Set ready checks for services that need to be ready before sandbox is usable.
5. Monitor Build Progress
Use progress and log callbacks to monitor long-running builds.
Next Steps