Langchain for Sandboxes - A unified Python interface for sandbox providers
Grainchain provides a clean, consistent API for interacting with various sandbox providers, enabling developers to write code once and run it across multiple sandbox environments. Just like Langchain abstracts LLM providers, Grainchain abstracts sandbox providers.
import asyncio
from grainchain import Sandbox
async def main():
# Create a sandbox with the default provider
async with Sandbox() as sandbox:
# Execute code
result = await sandbox.execute("echo 'Hello, Grainchain!'")
print(result.stdout) # "Hello, Grainchain!"
# Upload and run a Python script
await sandbox.upload_file("script.py", "print('Hello from Python!')")
result = await sandbox.execute("python script.py")
print(result.stdout) # "Hello from Python!"
asyncio.run(main())
Before using Grainchain, check which sandbox providers are available and properly configured:
# Check all providers
grainchain providers
# Show detailed setup instructions
grainchain providers --verbose
# Check specific provider
grainchain providers --check e2b
# Show only available providers
grainchain providers --available-only
Example output:
๐ง Grainchain Sandbox Providers
๐ Default provider: local โ
โ
LOCAL
Dependencies: โ
Configuration: โ
โ E2B
Dependencies: โ
Install: pip install grainchain[e2b]
Configuration: โ
Missing: E2B_API_KEY
Setup:
Set the following environment variables:
export E2B_API_KEY='your-e2b-api-key-here'
๐ Summary: 1/5 providers available
from grainchain import get_providers_info, get_available_providers, check_provider
# Get all provider information
providers = get_providers_info()
for name, info in providers.items():
print(f"{name}: {'๏ฟฝ๏ฟฝ๏ฟฝ' if info.available else 'โ'}")
# Get only available providers
available = get_available_providers()
print(f"Ready to use: {', '.join(available)}")
# Check specific provider
e2b_info = check_provider("e2b")
if not e2b_info.available:
print(f"E2B setup needed: {e2b_info.missing_config}")
Provider | Dependencies | Environment Variables | Install Command |
---|---|---|---|
Local | None | None | Built-in โ |
E2B | e2b |
E2B_API_KEY |
pip install grainchain[e2b] |
Modal | modal |
MODAL_TOKEN_ID , MODAL_TOKEN_SECRET |
pip install grainchain[modal] |
Daytona | daytona |
DAYTONA_API_KEY |
pip install daytona-sdk |
Morph | morphcloud |
MORPH_API_KEY |
pip install morphcloud |
Compare sandbox providers with comprehensive performance testing:
# Test individual providers
python benchmarks/scripts/grainchain_benchmark.py --providers local
python benchmarks/scripts/grainchain_benchmark.py --providers e2b
python benchmarks/scripts/grainchain_benchmark.py --providers daytona
python benchmarks/scripts/grainchain_benchmark.py --providers morph
# Test multiple providers at once
python benchmarks/scripts/grainchain_benchmark.py --providers local e2b --iterations 3
# Generate automated summary report
python benchmarks/scripts/auto_publish.py --generate-summary
Run comprehensive benchmarks across all available providers:
# Run full benchmark suite with all providers
python benchmarks/scripts/grainchain_benchmark.py --providers local e2b modal daytona morph --iterations 3
# Run automated benchmark and generate summary (used by CI)
python benchmarks/scripts/auto_publish.py --run-benchmark
# Generate summary from existing results
python benchmarks/scripts/auto_publish.py --generate-summary
The benchmark system generates timestamped reports in benchmarks/results/
that include:
- Performance comparison tables across providers
- Success rates and error analysis
- Detailed metrics for each test scenario
- JSON data for historical tracking
- Automated summary reports
Latest benchmark results (updated 2025-07-06):
Provider | Success Rate | Avg Time (s) | Status | Performance |
---|---|---|---|---|
Local | 100.0% | 1.39 | โ Production Ready | โก Fastest |
E2B | - | - | โ Not tested | ๐ Cloud-based |
Daytona | - | - | โ Not tested | ๐ก๏ธ Comprehensive |
Morph | - | - | โ Payment required | ๐ Instant Snapshots |
Performance Notes:
- Local: โ Production-ready with 100% success rate, fastest execution, perfect for development/testing
- E2B: Production-ready cloud sandboxes (requires API key setup)
- Daytona: Full workspace environments with comprehensive tooling
- Morph: Custom base images with instant snapshots (requires paid plan)
๐ SUCCESS: Local provider now achieves 100% success rate across all test scenarios! All operations including File Operations and Snapshot Lifecycle are working perfectly.
Results are automatically saved to benchmarks/results/
and can be committed to track performance over time.
View the full benchmark summary at benchmarks/results/SUMMARY.md
.
Comprehensive Benchmark Results (July 6, 2025)
Scenario | Local Success | Local Avg Time | E2B Success | E2B Avg Time | Winner |
---|---|---|---|---|---|
Basic Commands | 100% | 0.021s | 100% | 0.662s | ๐ Local (31x faster) |
Python Execution | 100% | 0.089s | 100% | 1.343s | ๐ Local (15x faster) |
File Operations | 100% | 0.001s | 100% | 1.343s | ๐ Local (1343x faster) |
Computational Tasks | 100% | 0.080s | 100% | 1.067s | ๐ Local (13x faster) |
Snapshot Lifecycle | 33% | 6.0s | 67% | 9.05s | ๐ E2B (better reliability) |
Key Insights:
- Local Provider: Exceptional speed across all scenarios, but snapshot functionality needs improvement
- E2B Provider: Consistent reliability with reasonable performance, excellent for production workloads
- Overall Recommendation: Use Local for development/testing, E2B for production deployments
For more statistically significant results, you can run high-iteration benchmarks with configurable iterations:
Command Line:
# Run 50 iterations (default) for comprehensive analysis
./scripts/benchmark_high_iteration.sh 50
# Run 100 iterations on specific providers
./scripts/benchmark_high_iteration.sh 100 "local e2b"
# Using the CLI command
uv run grainchain benchmark-high-iteration --iterations 50 --providers "local e2b"
GitHub Action (Manual Trigger):
- Go to Actions โ "High-Iteration Benchmarks (Manual)"
- Click "Run workflow"
- Configure iterations (default: 50) and providers
- Results will be available as workflow artifacts
Benefits of High-Iteration Testing:
- Statistical Significance: Detect smaller performance differences with confidence
- Confidence Intervals: 95% confidence intervals for all metrics
- Outlier Detection: Identify and analyze performance anomalies
- Trend Analysis: Better understanding of performance consistency
Note: High-iteration benchmarks are not part of CI/CD and must be run manually. They provide more reliable data for production deployment decisions.
The sandbox ecosystem is rapidly expanding with providers like E2B, Daytona, Morph, and others. Each has different APIs and capabilities, creating:
- Vendor Lock-in: Applications become tightly coupled to specific providers
- Learning Curve: Developers must learn multiple APIs
- Migration Complexity: Switching providers requires significant code changes
- Testing Challenges: Testing across multiple providers is cumbersome
Grainchain solves these problems with a unified interface that abstracts provider-specific implementations.
โโโโโโโโโโโโโโโโโโโ
โ Application โ
๏ฟฝ๏ฟฝ๏ฟฝ๏ฟฝ๏ฟฝ๏ฟฝ๏ฟฝโโโโโโโโโโโโโโโโโโ
โ
โโโโโโโโโโโ๏ฟฝ๏ฟฝ๏ฟฝโโโโโโโ
โ Grainchain โ
โ Core API โ
โโโโโโโโโโโโโโโโโโโ
โ
โโโโโโโโโโโโโโโโโโโ
โ Provider โ
โ Adapters โ
โโโโโโโโโโโโโโโโโโโ
โ
โโโโโโโโโโโโโโโโโโโ
โ Sandbox โ
โ Providers โ
โ (E2B, Daytona) โ
โโโโโโโโโโโโโโโโโโโ
# Basic installation
pip install grainchain
# With E2B support
pip install grainchain[e2b]
# With Daytona support
pip install grainchain[daytona]
# With Morph support
pip install grainchain[morph]
# With Local provider support
pip install grainchain[local]
# With Docker provider support
pip install grainchain[docker]
# With all sandbox providers
pip install grainchain[all]
# For benchmarking (docker, psutil)
pip install grainchain[benchmark]
# For data science examples (numpy, pandas, matplotlib)
pip install grainchain[examples]
# Clone the repository
git clone https://github.com/codegen-sh/grainchain.git
cd grainchain
# Set up development environment with uv
uv venv
source .venv/bin/activate # On Windows: .venv\Scripts\activate
# Install core development dependencies
uv sync --extra dev
# Optional: Install benchmarking tools (if you need docker benchmarks)
uv sync --extra benchmark
# Optional: Install data science dependencies (if you need examples)
uv sync --extra examples
# Or install everything
uv sync --all-extras
# Install pre-commit hooks
grainchain install-hooks
Provider | Status | Features |
---|---|---|
E2B | โ Supported | Code interpreter, custom images, file operations |
Daytona | โ Supported | Development environments, workspace management |
Morph | โ Supported | Custom base images, instant snapshots, <250ms startup |
Local | โ Supported | Local development and testing |
Docker | ๐ง Planned | Local Docker containers |
If you encounter SSL certificate errors with Daytona:
SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self-signed certificate
This typically indicates:
- Development Environment: The API endpoint may be using self-signed certificates
- API Key Environment: Ensure your API key matches the intended environment (production vs staging)
- Network Issues: Check if you're behind a corporate firewall
Solution: Verify your Daytona API key is for the correct environment and contact Daytona support if the issue persists.
Morph.so provides instant snapshots and custom base images with <250ms startup times. Key configuration options:
from grainchain import Sandbox, SandboxConfig
# Basic Morph configuration
config = SandboxConfig(
provider_config={
"image_id": "morphvm-minimal", # or your custom base image
"vcpus": 2, # CPU cores
"memory": 2048, # Memory in MB
"disk_size": 8192, # Disk size in MB
}
)
async with Sandbox(provider="morph", config=config) as sandbox:
# Your code here
pass
Key Features:
- Custom Base Images: Use
image_id
to specify your custom-configured base image - Instant Snapshots: Create and restore snapshots in milliseconds
- Fast Startup: <250ms startup times for rapid development cycles
- Resource Control: Fine-tune CPU, memory, and disk allocation
Environment Variables:
export MORPH_API_KEY=your-morph-api-key
from grainchain import Sandbox
# Use default provider (configured via environment or config file)
async with Sandbox() as sandbox:
result = await sandbox.execute("pip install requests")
result = await sandbox.execute("python -c 'import requests; print(requests.__version__)'")
from grainchain import Sandbox
# Use specific provider
async with Sandbox(provider="e2b") as sandbox:
result = await sandbox.execute("echo 'Using E2B'")
async with Sandbox(provider="daytona") as sandbox:
result = await sandbox.execute("echo 'Using Daytona'")
async with Sandbox(provider="local") as sandbox:
result = await sandbox.execute("echo 'Using Local'")
async with Sandbox(provider="morph") as sandbox:
result = await sandbox.execute("echo 'Using Morph'")
from grainchain import Sandbox, SandboxConfig
config = SandboxConfig(
timeout=300,
memory_limit="2GB",
cpu_limit=2.0,
environment_vars={"API_KEY": "secret"},
working_directory="/workspace"
)
async with Sandbox(provider="e2b", config=config) as sandbox:
result = await sandbox.execute("echo $API_KEY")
async with Sandbox() as sandbox:
# Upload files
await sandbox.upload_file("data.csv", csv_content)
await sandbox.upload_file("script.py", python_code)
# Execute uploaded script
result = await sandbox.execute("python script.py")
# Download results
output = await sandbox.download_file("results.json")
# List files
files = await sandbox.list_files("/workspace")
for file in files:
print(f"{file.name}: {file.size} bytes")
async with Sandbox(provider="local") as sandbox:
# Set up environment
await sandbox.execute("pip install numpy")
await sandbox.upload_file("data.py", "import numpy as np")
# Create snapshot
snapshot_id = await sandbox.create_snapshot()
# Make changes
await sandbox.execute("pip install pandas")
# Restore to snapshot
await sandbox.restore_snapshot(snapshot_id)
# Default provider
export GRAINCHAIN_DEFAULT_PROVIDER=e2b
# E2B configuration
export E2B_API_KEY=your-e2b-key
export E2B_TEMPLATE=python-data-science
# Daytona configuration
export DAYTONA_API_KEY=your-daytona-key
export DAYTONA_WORKSPACE_TEMPLATE=python-dev
# Morph configuration
export MORPH_API_KEY=your-morph-key
export MORPH_TEMPLATE=custom-base-image
Create grainchain.yaml
in your project root:
default_provider: e2b
providers:
e2b:
api_key: ${E2B_API_KEY}
template: python-data-science
timeout: 300
daytona:
api_key: ${DAYTONA_API_KEY}
timeout: 300
morph:
api_key: ${MORPH_API_KEY}
template: custom-base-image
timeout: 300
sandbox_defaults:
timeout: 180
working_directory: /workspace
auto_cleanup: true
Check out the examples directory for comprehensive usage examples:
basic_usage.py
- Core functionality and provider usagedata_analysis.py
- Data science workflow example
# Set up development environment
uv venv
source .venv/bin/activate
uv sync --all-extras
# Install pre-commit hooks
grainchain install-hooks
# Run tests
grainchain test
# Run tests with coverage
grainchain test --cov
# Format and fix code
grainchain format
# Lint code
grainchain lint --fix
# Type check (currently disabled)
grainchain typecheck
# Run all quality checks
grainchain check
# Run benchmarks
grainchain benchmark --provider local
# Generate comprehensive performance report (committable)
./scripts/benchmark_all.sh
# Check latest performance status
./scripts/benchmark_status.sh
Grainchain includes a comprehensive CLI for development:
grainchain --help # Show all commands
grainchain providers # Check provider availability
grainchain providers --verbose # Show detailed setup instructions
grainchain test # Run pytest
grainchain test --cov # Run tests with coverage
grainchain lint # Run ruff linting
grainchain format # Format with ruff
grainchain typecheck # Type checking (temporarily disabled)
grainchain benchmark # Run performance benchmarks
grainchain install-hooks # Install pre-commit hooks
grainchain check # Run all quality checks
All code is automatically checked with:
- Ruff - Fast Python linting, formatting, and import sorting
- mypy - Static type checking (temporarily disabled)
- Pre-commit hooks - Automated quality checks
- Core interface design
- Base provider abstraction
- Configuration system
- E2B provider implementation
- Daytona provider implementation
- Morph provider implementation
- Local provider for testing
- Comprehensive test suite
- Error handling improvements
- Performance optimizations
- Documentation website
- Docker provider
- Plugin system for custom providers
- Monitoring and observability
- Cost optimization features
We welcome contributions! Please see our Contributing Guide for details.
- Fork the repository
- Create a feature branch
- Set up development environment:
uv sync --all-extras
- Make your changes
- Run quality checks:
grainchain check
- Submit a pull request
MIT License - see LICENSE for details.
- Inspired by Langchain for LLM abstraction
- Built for the E2B, Daytona, and Morph communities
- Thanks to all contributors and early adopters
Built with โค๏ธ by the Codegen team