Configuration Guide¶
This guide covers all configuration options available in LLM Sandbox.
Session Configuration¶
Basic Parameters¶
from llm_sandbox import SandboxSession
session = SandboxSession(
lang="python", # Programming language
verbose=True, # Enable verbose logging
keep_template=False, # Keep container image after session
workdir="/sandbox", # Working directory in container
)
Timeout Configuration¶
LLM Sandbox provides comprehensive timeout controls to prevent runaway code execution and manage resource usage efficiently.
Timeout Types¶
There are three types of timeouts you can configure:
Timeout Type | Description | Default |
---|---|---|
default_timeout | Default timeout for all operations | 30.0 seconds |
execution_timeout | Timeout for code execution (per run) | Uses default_timeout |
session_timeout | Maximum session lifetime | None (unlimited) |
Basic Timeout Configuration¶
from llm_sandbox import SandboxSession
# Configure timeouts at session creation
with SandboxSession(
lang="python",
default_timeout=30.0, # Default timeout for operations
execution_timeout=60.0, # Timeout for code execution
session_timeout=300.0, # Session expires after 5 minutes
verbose=True
) as session:
# Fast operation - should complete
result = session.run("""
print("Hello, World!")
import time
time.sleep(2)
print("Operation completed")
""")
Per-Execution Timeout Override¶
You can override the execution timeout for individual run()
calls:
with SandboxSession(lang="python", execution_timeout=10.0) as session:
# This will use the session's execution_timeout (10 seconds)
result1 = session.run("print('Normal execution')")
# Override with a longer timeout for this specific execution
result2 = session.run("""
import time
time.sleep(15) # This needs more time
print("Long operation completed")
""", timeout=20.0) # Override with 20 seconds
# Override with a shorter timeout
try:
session.run("""
import time
time.sleep(5)
print("This might timeout")
""", timeout=2.0) # Override with 2 seconds
except SandboxTimeoutError:
print("Operation timed out as expected")
Timeout Error Handling¶
from llm_sandbox.exceptions import SandboxTimeoutError
def execute_with_retry(session, code, max_retries=3):
"""Execute code with automatic retry on timeout."""
for attempt in range(max_retries):
try:
return session.run(code, timeout=10.0)
except SandboxTimeoutError:
print(f"Attempt {attempt + 1} timed out")
if attempt == max_retries - 1:
raise
print("Retrying...")
# Usage example
with SandboxSession(lang="python") as session:
try:
result = execute_with_retry(session, """
import time
import random
time.sleep(random.uniform(5, 15)) # Variable execution time
print("Completed!")
""")
print(result.stdout)
except SandboxTimeoutError:
print("All retry attempts failed")
Backend-Specific Timeout Behavior¶
Different backends handle timeouts differently:
Docker & Podman¶
- Containers are forcefully killed when timeout is reached
- Container cleanup is automatic
- Resource usage monitoring during execution
Kubernetes¶
- Pods are monitored for timeout during command execution
- Timeout applies to individual command execution within the pod
- Pod lifecycle is managed independently
Advanced Timeout Scenarios¶
Infinite Loop Protection¶
with SandboxSession(lang="python", execution_timeout=5.0) as session:
try:
session.run("""
# This infinite loop will be terminated
i = 0
while True:
i += 1
if i % 100000 == 0:
print(f"Iteration: {i}")
""")
except SandboxTimeoutError:
print("Infinite loop was terminated by timeout")
Resource-Intensive Operation Control¶
with SandboxSession(lang="python") as session:
try:
session.run("""
# CPU-intensive operation
total = 0
for i in range(10**8): # Large computation
total += i * i
print(f"Result: {total}")
""", timeout=30.0) # Give enough time for legitimate computation
except SandboxTimeoutError:
print("Computation took too long and was terminated")
Session Lifetime Management¶
import time
# Session that automatically expires
with SandboxSession(
lang="python",
session_timeout=60.0 # Session expires after 1 minute
) as session:
# This will work
session.run("print('First execution')")
# Wait and try again
time.sleep(30)
session.run("print('Second execution')")
# This might fail if session has expired
time.sleep(40) # Total elapsed: 70 seconds
try:
session.run("print('This might fail')")
except SandboxTimeoutError:
print("Session expired")
Best Practices¶
- Set Appropriate Timeouts: Balance between allowing legitimate long operations and preventing runaway code
- Use Per-Execution Overrides: Override timeouts for known long-running operations
- Implement Retry Logic: Handle timeout errors gracefully with retry mechanisms
- Monitor Resource Usage: Use timeout in combination with resource limits
- Log Timeout Events: Enable verbose logging to understand timeout patterns
Language Options¶
Supported languages and their identifiers:
Language | Identifier | Default Image |
---|---|---|
Python | python | ghcr.io/vndee/sandbox-python-311-bullseye |
JavaScript | javascript | ghcr.io/vndee/sandbox-node-22-bullseye |
Java | java | ghcr.io/vndee/sandbox-java-11-bullseye |
C++ | cpp | ghcr.io/vndee/sandbox-cpp-11-bullseye |
Go | go | ghcr.io/vndee/sandbox-go-123-bullseye |
Ruby | ruby | ghcr.io/vndee/sandbox-ruby-302-bullseye |
Container Images¶
Using Default Images¶
Using Custom Images¶
# Use a specific image
with SandboxSession(
lang="python",
image="python:3.12-slim"
) as session:
pass
# Use your own custom image
with SandboxSession(
lang="python",
image="myregistry.com/my-python:latest"
) as session:
pass
Building from Dockerfile¶
# Build image from Dockerfile
with SandboxSession(
lang="python",
dockerfile="./custom/Dockerfile"
) as session:
pass
Example Dockerfile:
FROM python:3.11-slim
# Install additional system packages
RUN apt-get update && apt-get install -y \
build-essential \
&& rm -rf /var/lib/apt/lists/*
# Pre-install Python packages
RUN pip install numpy pandas matplotlib
WORKDIR /sandbox
Runtime Configuration¶
Important: Runtime configurations work differently depending on the backend:
Docker and Podman Backends¶
For Docker and Podman backends, runtime configuration options are passed as extra arguments to the respective Python libraries (docker-py
and podman-py
). These are used to configure container creation and execution parameters.
Docker Runtime Config¶
# Docker-specific runtime configuration
runtime_config = {
"privileged": False,
"memory": "512m",
"cpu_period": 100000,
"cpu_quota": 50000,
"network_mode": "bridge",
"volumes": {"/host/path": {"bind": "/container/path", "mode": "ro"}},
"environment": {"PYTHONPATH": "/app"},
"working_dir": "/workspace"
}
session = SandboxSession(
image="python:3.9",
backend="docker",
runtime_config=runtime_config
)
Docker Documentation: See the Docker SDK for Python documentation for complete API reference and available parameters.
Podman Runtime Config¶
# Podman-specific runtime configuration
runtime_config = {
"privileged": False,
"memory": "512m",
"cpu_shares": 512,
"network_mode": "bridge",
"volumes": {"/host/path": {"bind": "/container/path", "mode": "ro"}},
"environment": {"PYTHONPATH": "/app"},
"working_dir": "/workspace"
}
session = SandboxSession(
image="python:3.9",
backend="podman",
runtime_config=runtime_config
)
Podman Documentation: See the Podman Python SDK documentation for complete API reference and available parameters.
Kubernetes Backend¶
For Kubernetes, runtime configurations are not supported through the runtime_config
parameter. Instead, users should define their requirements as Kubernetes Pod manifests using the pod_manifest
parameter.
# Kubernetes configuration using pod_manifest parameter
import uuid
# Generate unique pod name to avoid conflicts
unique_suffix = str(uuid.uuid4())[:8]
pod_name = f"sandbox-{unique_suffix}"
# Define custom pod manifest
pod_manifest = {
"apiVersion": "v1",
"kind": "Pod",
"metadata": {
"name": pod_name,
"labels": {"app": "sandbox"},
},
"spec": {
"containers": [
{
"name": "sandbox-container",
"image": "python:3.9",
"tty": True,
"securityContext": {
"runAsUser": 1000,
"runAsGroup": 1000,
},
"resources": {
"limits": {
"memory": "512Mi",
"cpu": "500m"
},
"requests": {
"memory": "256Mi",
"cpu": "250m"
}
}
}
],
"securityContext": {
"runAsUser": 1000,
"runAsGroup": 1000,
},
},
}
session = SandboxSession(
backend="kubernetes",
lang="python",
image="python:3.9",
pod_manifest=pod_manifest,
workdir="/tmp/sandbox" # Use writable directory for non-root
)
To configure resources, security context, volumes, and other Pod-level settings in Kubernetes, you should:
- Create a Pod manifest file or use the Kubernetes Python client directly
- Apply resource limits, security policies, and other configurations through Kubernetes APIs
- Use ConfigMaps and Secrets for environment configuration
Kubernetes Documentation: See the Kubernetes Python Client documentation and Kubernetes API reference for Pod configuration options.
Example Runtime Configurations¶
Resource Limits (Docker/Podman)¶
# Memory and CPU limits
runtime_config = {
"memory": "1g", # 1GB memory limit
"cpu_period": 100000, # CPU period in microseconds
"cpu_quota": 50000, # CPU quota (50% of one CPU)
"memswap_limit": "2g" # Memory + swap limit
}
Network Configuration (Docker/Podman)¶
# Custom network settings
runtime_config = {
"network_mode": "host", # Use host networking
"ports": {"8080/tcp": 8080}, # Port mapping
"dns": ["8.8.8.8", "8.8.4.4"] # Custom DNS servers
}
Volume Mounts (Docker/Podman)¶
# Volume mounting
runtime_config = {
"volumes": {
"/host/data": {"bind": "/data", "mode": "rw"},
"/host/config": {"bind": "/config", "mode": "ro"}
}
}
Environment Variables (Docker/Podman)¶
# Environment configuration
runtime_config = {
"environment": {
"PYTHONPATH": "/app:/libs",
"DEBUG": "true",
"API_KEY": "your-api-key"
}
}
Security Configuration (Docker/Podman)¶
# Security settings
runtime_config = {
"privileged": False,
"user": "1000:1000", # Run as specific user/group
"cap_drop": ["ALL"], # Drop all capabilities
"cap_add": ["NET_ADMIN"], # Add specific capabilities
"security_opt": ["no-new-privileges:true"]
}
Backend-Specific Documentation Links¶
- Docker: Docker SDK for Python - Complete API reference for container configuration
- Podman: Podman Python SDK - Complete API reference for Podman container management
- Kubernetes: Kubernetes Python Client - Official Kubernetes API client documentation
For detailed parameter lists and advanced configuration options, please refer to the respective documentation links above.
Security Configuration¶
Security Policies¶
from llm_sandbox.security import (
SecurityPolicy,
SecurityPattern,
RestrictedModule,
SecurityIssueSeverity
)
# Create custom security policy
policy = SecurityPolicy(
severity_threshold=SecurityIssueSeverity.MEDIUM,
patterns=[
SecurityPattern(
pattern=r"os\.system",
description="System command execution",
severity=SecurityIssueSeverity.HIGH
),
SecurityPattern(
pattern=r"open\s*\([^)]*['\"][wa]",
description="File write operation",
severity=SecurityIssueSeverity.MEDIUM
)
],
restricted_modules=[
RestrictedModule(
name="subprocess",
description="Process execution",
severity=SecurityIssueSeverity.HIGH
)
]
)
with SandboxSession(lang="python", security_policy=policy) as session:
pass
For more information, see the Security Policies page.
Custom Client Configuration¶
By default, LLM Sandbox uses the standard client initialization for each backend:
- Docker:
docker.from_env()
- Podman:
PodmanClient()
- Kubernetes: Loads from
~/.kube/config
However, you can provide your own client instances to connect to remote servers, custom sockets, or clusters with specific configurations.
Docker Remote Connection¶
import docker
# Connect to remote Docker daemon
client = docker.DockerClient(
base_url="tcp://remote-docker-host:2376",
tls=True,
timeout=30
)
with SandboxSession(
backend="docker",
client=client, # Use custom client instead of docker.from_env()
lang="python"
) as session:
pass
Podman Custom Socket¶
from podman import PodmanClient
# Connect to custom Podman socket
client = PodmanClient(
base_url="unix:///run/user/1000/podman/podman.sock",
timeout=60
)
with SandboxSession(
backend="podman",
client=client, # Use custom client
lang="python"
) as session:
pass
Kubernetes Remote Cluster¶
from kubernetes import client, config
# Load config from custom file or remote cluster
config.load_kube_config(
config_file="/path/to/custom/kubeconfig",
context="remote-cluster-context"
)
# Or configure for remote cluster programmatically
configuration = client.Configuration()
configuration.host = "https://k8s-cluster.example.com:6443"
configuration.api_key_prefix['authorization'] = 'Bearer'
configuration.api_key['authorization'] = 'your-token-here'
k8s_client = client.CoreV1Api(client.ApiClient(configuration))
with SandboxSession(
backend="kubernetes",
client=k8s_client, # Use custom configured client
lang="python",
kube_namespace="custom-namespace"
) as session:
pass
Docker with Custom TLS Configuration¶
import docker
import ssl
# Docker with custom TLS/SSL settings
tls_config = docker.tls.TLSConfig(
client_cert=('/path/to/client-cert.pem', '/path/to/client-key.pem'),
ca_cert='/path/to/ca.pem',
verify=True
)
client = docker.DockerClient(
base_url="tcp://secure-docker-host:2376",
tls=tls_config
)
with SandboxSession(backend="docker", client=client, lang="python") as session:
pass
Advanced Configuration¶
Artifact Extraction¶
from llm_sandbox import ArtifactSandboxSession
with ArtifactSandboxSession(
lang="python",
enable_plotting=True,
verbose=True
) as session:
result = session.run("""
import matplotlib.pyplot as plt
plt.plot([1, 2, 3], [1, 4, 9])
plt.show()
""")
# Access captured plots
for plot in result.plots:
print(f"Plot format: {plot.format}")
print(f"Plot size: {len(plot.content_base64)} bytes")
Custom Language Handlers¶
from llm_sandbox.language_handlers import AbstractLanguageHandler
from llm_sandbox.language_handlers.factory import LanguageHandlerFactory
class CustomLanguageHandler(AbstractLanguageHandler):
def __init__(self, logger=None):
super().__init__(logger)
self.config = LanguageConfig(
name="custom",
file_extension="custom",
execution_commands=["custom-runner {file}"],
package_manager="custom-pm install"
)
def get_import_patterns(self, module):
return rf"import\s+{module}"
# Implement other required methods...
# Register custom handler
LanguageHandlerFactory.register_handler("custom", CustomLanguageHandler)
# Use custom language
with SandboxSession(lang="custom") as session:
pass
Logging Configuration¶
import logging
# Configure logging
logging.basicConfig(
level=logging.DEBUG,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
# Create logger
logger = logging.getLogger('llm_sandbox')
# Use custom logger
with SandboxSession(
lang="python",
logger=logger,
verbose=True
) as session:
pass
Session Persistence¶
# Keep container running for reuse
with SandboxSession(
lang="python",
keep_template=True,
commit_container=True
) as session:
# Install packages
session.install(["numpy", "pandas", "scikit-learn"])
# Run initial setup
session.run("""
import numpy as np
import pandas as pd
from sklearn import datasets
print("Environment ready!")
""")
# Container state is saved and can be reused
Configuration Best Practices¶
1. Use Appropriate Resource Limits¶
# Development environment
dev_config = {
"cpu_count": 4,
"mem_limit": "2g",
\}
# Production environment
prod_config = {
"cpu_count": 1,
"mem_limit": "256m",
\ "pids_limit": 50
}
2. Layer Security Policies¶
# Base policy
base_policy = get_security_policy("production")
# Add custom patterns
base_policy.add_pattern(SecurityPattern(
pattern=r"requests\.get\s*\(.*internal",
description="Internal network access",
severity=SecurityIssueSeverity.HIGH
))
3. Use Environment-Specific Images¶
import os
# Environment-based configuration
env = os.getenv("ENVIRONMENT", "development")
configs = {
"development": {
"image": "python:3.11",
"keep_template": True,
"verbose": True
},
"production": {
"image": "python:3.11-slim",
"keep_template": False,
"verbose": False
}
}
with SandboxSession(**configs[env]) as session:
pass
4. Handle Backend Failover¶
def create_session_with_fallback(**kwargs):
"""Create session with backend fallback"""
backends = [
SandboxBackend.DOCKER,
SandboxBackend.PODMAN,
SandboxBackend.KUBERNETES
]
for backend in backends:
try:
return SandboxSession(backend=backend, **kwargs)
except Exception as e:
print(f"Backend {backend} failed: {e}")
continue
raise RuntimeError("No available backends")
Next Steps¶
- Learn about Security Policies
- Explore Backend Options
- Check out Examples
- Read the API Reference