This guide covers production-ready patterns and best practices for working with Hopx Sandboxes, including error handling, performance optimization, security, and resource management.
Always Use Context Managers
Always use context managers (Python) or try/finally blocks (JavaScript) for automatic cleanup:
Python
JavaScript/TypeScript
# ✅ GOOD: Context manager ensures cleanup
with Sandbox.create(template="code-interpreter", api_key=API_KEY) as sandbox:
result = sandbox.run_code("print('Hello')")
print(result.stdout)
# Sandbox automatically deleted here
# ❌ BAD: Manual cleanup (easy to forget)
sandbox = Sandbox.create(template="code-interpreter", api_key=API_KEY)
result = sandbox.run_code("print('Hello')")
# If an exception occurs, sandbox.kill() might not be called!
sandbox.kill()
Comprehensive Error Handling
Handle errors properly with specific exception types:
Python
JavaScript/TypeScript
from hopx_ai.errors import (
AuthenticationError,
NotFoundError,
ResourceLimitError,
CodeExecutionError,
HopxError
)
import logging
logger = logging.getLogger(__name__)
try:
with Sandbox.create(template="code-interpreter", api_key=API_KEY) as sandbox:
# Try file operation
try:
content = sandbox.files.read("/non-existent.txt")
except NotFoundError as e:
logger.warning(f"File not found: {e.message} (Request ID: {e.request_id})")
# Fallback: create the file
sandbox.files.write("/non-existent.txt", "Default content")
content = sandbox.files.read("/non-existent.txt")
print(f"Recovered with fallback: {content}")
# Try code execution
try:
result = sandbox.run_code("1/0", timeout=5)
except CodeExecutionError as e:
logger.error(f"Code execution failed: {e.message}")
print("Caught code execution error")
except AuthenticationError as e:
logger.error(f"Authentication failed: {e.message}")
except ResourceLimitError as e:
logger.error(f"Resource limit exceeded: {e.message}")
except HopxError as e:
logger.error(f"API error: {e.message} (Status: {e.status_code})")
Optimize performance with these techniques:
Python
JavaScript/TypeScript
with Sandbox.create(template="code-interpreter", api_key=API_KEY) as sandbox:
# ✅ GOOD: Set environment variables once
sandbox.env.set_all({
"DATABASE_URL": "postgres://...",
"REDIS_URL": "redis://...",
"API_KEY": "sk-..."
})
# ✅ GOOD: Batch file operations
files_to_write = {
"/workspace/file1.txt": "Content 1",
"/workspace/file2.txt": "Content 2",
"/workspace/file3.txt": "Content 3"
}
for path, content in files_to_write.items():
sandbox.files.write(path, content)
# ✅ GOOD: Use async execution for long-running tasks
execution_id = sandbox.run_code_async("""
import time
# Long computation
time.sleep(10)
print("Done!")
""")
# Do other work while code executes
# ...
Security Best Practices
Follow these security guidelines:
Python
JavaScript/TypeScript
import os
# ✅ GOOD: Use environment variables for secrets
API_KEY = os.getenv("HOPX_API_KEY")
SECRET_KEY = os.getenv("SECRET_KEY")
with Sandbox.create(template="code-interpreter", api_key=API_KEY) as sandbox:
# ✅ GOOD: Pass secrets via env parameter, not in code
result = sandbox.run_code(
"""
import os
api_key = os.environ.get('API_KEY')
# Use api_key securely
""",
env={
"API_KEY": SECRET_KEY # Passed securely
}
)
# ❌ BAD: Never hardcode secrets in code
# result = sandbox.run_code("api_key = 'sk-hardcoded-secret'")
Never hardcode API keys, passwords, or other secrets in your code. Always use environment variables passed through the env parameter.
Resource Management
Manage resources efficiently:
Python
JavaScript/TypeScript
# ✅ GOOD: Reuse sandbox for multiple operations
with Sandbox.create(template="code-interpreter", api_key=API_KEY) as sandbox:
# Set up once
sandbox.env.set_all({"CONFIG": "value"})
sandbox.files.write("/workspace/config.json", '{"key": "value"}')
# Run multiple operations
result1 = sandbox.run_code("print('Operation 1')")
result2 = sandbox.run_code("print('Operation 2')")
result3 = sandbox.run_code("print('Operation 3')")
# Cleanup happens automatically
# ❌ BAD: Create new sandbox for each operation
# sandbox1 = Sandbox.create(...)
# sandbox1.run_code("...")
# sandbox1.kill()
# sandbox2 = Sandbox.create(...)
# sandbox2.run_code("...")
# sandbox2.kill()
Retry Strategies
Implement retry logic for transient failures:
Python
JavaScript/TypeScript
import time
from hopx_ai.errors import HopxError
def create_sandbox_with_retry(max_retries=3, delay=1):
for attempt in range(max_retries):
try:
return Sandbox.create(
template="code-interpreter",
api_key=API_KEY
)
except HopxError as e:
if attempt < max_retries - 1:
logger.warning(f"Attempt {attempt + 1} failed, retrying...")
time.sleep(delay * (attempt + 1)) # Exponential backoff
else:
raise
return None
sandbox = create_sandbox_with_retry()
try:
# Use sandbox
result = sandbox.run_code("print('Hello')")
finally:
sandbox.kill()
Monitoring and Logging
Add logging and monitoring to your sandbox operations:
Python
JavaScript/TypeScript
import logging
import time
logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO)
with Sandbox.create(template="code-interpreter", api_key=API_KEY) as sandbox:
start_time = time.time()
logger.info(f"Sandbox created: {sandbox.sandbox_id}")
# Monitor execution
result = sandbox.run_code("print('Hello')")
execution_time = time.time() - start_time
logger.info(f"Code executed in {execution_time:.2f}s")
logger.info(f"Exit code: {result.exit_code}")
# Get sandbox metrics
metrics = sandbox.get_metrics_snapshot()
logger.info(f"Active executions: {metrics.get('active_executions', 0)}")
logger.info(f"Uptime: {metrics.get('uptime_seconds', 0):.2f}s")
logger.info(f"Error count: {metrics.get('error_count', 0)}")
Next Steps