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}")
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)
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")
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
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}")
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