Complete E2B Code Interpreter Tutorial: Secure Code Execution for AI Applications
E2B Code Interpreter is a sandboxed code execution platform that enables AI applications to run code safely in isolated environments. In this tutorial, we'll learn how to use E2B to build AI applications that can execute Python code, generate visualizations, and process data in real-time.
What Is E2B?
E2B (Environment to Binary) is a cloud platform that provides sandboxes for code execution. These sandboxes run in isolated microVMs, ensuring that executed code cannot affect the host system. E2B is particularly useful for building AI agents that need to run code, code interpreters, data analysis tools, and other interactive AI applications.
Key advantages of E2B:
- Security: Each sandbox runs in an isolated microVM with separate filesystem and network
- Speed: Sandboxes can be spun up in milliseconds
- Flexibility: Supports Python, JavaScript, R, and other languages
- Integration: SDKs available for Python and JavaScript/TypeScript
- Persistence: Supports file upload/download and data persistence between executions
Installation
Prerequisites
Before getting started, make sure you have:
- Python 3.8+ or Node.js 18+
- An E2B account (free for basic usage)
- An API key from the E2B dashboard
Python SDK Installation
pip install e2b-code-interpreter
JavaScript/TypeScript SDK Installation
npm install @e2b/code-interpreter
Getting Your API Key
export E2BAPIKEY="e2bxxxxxxxxxxxxxxxxxxxx"
Or create a .env file:
E2BAPIKEY=e2bxxxxxxxxxxxxxxxxxxxx
Basic Usage
Running Simple Python Code
Here's a basic example of running Python code in an E2B sandbox:
from e2bcodeinterpreter import Sandbox
Create a new sandbox
sandbox = Sandbox()
Run Python code
execution = sandbox.runcode("print('Hello from E2B sandbox!')")
Get the output
print(execution.text) # Output: Hello from E2B sandbox!
Close the sandbox when done
sandbox.close()
Using Context Manager
A more idiomatic approach using context managers:
from e2bcodeinterpreter import Sandbox
with Sandbox() as sandbox:
execution = sandbox.run
code("""
import sys
print(f"Python version: {sys.version}")
print(f"Platform: {sys.platform}")
""")
print(execution.text)
Running Multiple Cells
You can run multiple code blocks sequentially, and state is preserved between executions:
from e2bcodeinterpreter import Sandbox
with Sandbox() as sandbox:
# Cell 1: Define variables
sandbox.runcode("""
x = 10
y = 20
data = [1, 2, 3, 4, 5]
""")
# Cell 2: Use variables from the previous cell
execution = sandbox.runcode("""
result = x + y
filtered = [d for d in data if d > 2]
print(f"Sum: {result}")
print(f"Filtered: {filtered}")
""")
print(execution.text)
# Output:
# Sum: 30
# Filtered: [3, 4, 5]
Error Handling
E2B provides detailed error information:
from e2bcodeinterpreter import Sandbox
with Sandbox() as sandbox:
execution = sandbox.runcode("""
This code will produce an error
result = 1 / 0
""")
if execution.error:
print(f"Error type: {execution.error.name}")
print(f"Error message: {execution.error.value}")
print(f"Traceback: {execution.error.traceback}")
else:
print(execution.text)
Working with Files
Uploading Files to Sandbox
from e2bcodeinterpreter import Sandbox
with Sandbox() as sandbox:
# Upload a file from the local filesystem
with open("data.csv", "rb") as f:
sandbox.files.write("/home/user/data.csv", f.read())
# Verify the file was uploaded
execution = sandbox.run
code("""
import os
files = os.listdir('/home/user/')
print(files)
""")
print(execution.text)
Downloading Files from Sandbox
from e2bcodeinterpreter import Sandbox
with Sandbox() as sandbox:
# Generate a file in the sandbox
sandbox.runcode("""
import json
data = {
"users": [
{"name": "Alice", "age": 30},
{"name": "Bob", "age": 25}
]
}
with open('/home/user/output.json', 'w') as f:
json.dump(data, f, indent=2)
""")
# Download the file from the sandbox
content = sandbox.files.read("/home/user/output.json")
print(content.decode('utf-8'))
Managing Directories
from e2bcodeinterpreter import Sandbox
with Sandbox() as sandbox:
# Create a directory
sandbox.files.make
dir("/home/user/project")
# List directory contents
files = sandbox.files.list("/home/user/")
for f in files:
print(f"{f.name} - {'dir' if f.isdir else 'file'}")
Creating Visualizations
One of E2B's most useful features is the ability to generate charts and visualizations:
Matplotlib Charts
from e2bcodeinterpreter import Sandbox
with Sandbox() as sandbox:
execution = sandbox.run
code("""
import matplotlib.pyplot as plt
import numpy as np
Generate data
x = np.linspace(0, 10, 100)
y1 = np.sin(x)
y2 = np.cos(x)
Create plot
fig, ax = plt.subplots(figsize=(10, 6))
ax.plot(x, y1, label='sin(x)', color='blue', linewidth=2)
ax.plot(x, y2, label='cos(x)', color='red', linewidth=2)
ax.setxlabel('x')
ax.setylabel('y')
ax.settitle('Trigonometric Functions')
ax.legend()
ax.grid(True, alpha=0.3)
plt.tightlayout()
plt.show()
""")
# Get chart results as images
for result in execution.results:
if hasattr(result, 'png'):
# Save as PNG file
with open("chart.png", "wb") as f:
import base64
f.write(base64.b64decode(result.png))
print("Chart saved to chart.png")
Data Analysis with Pandas
from e2bcodeinterpreter import Sandbox
with Sandbox() as sandbox:
execution = sandbox.runcode("""
import pandas as pd
import matplotlib.pyplot as plt
Create sample dataset
data = {
'Month': ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun'],
'Revenue': [15000, 18000, 22000, 19000, 25000, 28000],
'Expenses': [12000, 13000, 15000, 14000, 16000, 17000]
}
df = pd.DataFrame(data)
Calculate profit
df['Profit'] = df['Revenue'] - df['Expenses']
Display statistics
print("=== Financial Summary ===")
print(f"Total Revenue: ${df['Revenue'].sum():,.0f}")
print(f"Total Expenses: ${df['Expenses'].sum():,.0f}")
print(f"Total Profit: ${df['Profit'].sum():,.0f}")
print(f"Average Monthly Profit: ${df['Profit'].mean():,.0f}")
print()
print(df.tostring(index=False))
Create visualization
fig, axes = plt.subplots(1, 2, figsize=(14, 5))
Bar chart
x = range(len(df))
width = 0.35
axes[0].bar([i - width/2 for i in x], df['Revenue'], width, label='Revenue', color='#2196F3')
axes[0].bar([i + width/2 for i in x], df['Expenses'], width, label='Expenses', color='#FF5722')
axes[0].setxticks(x)
axes[0].setxticklabels(df['Month'])
axes[0].settitle('Revenue vs Expenses')
axes[0].legend()
axes[0].setylabel('Amount ($)')
Line chart for profit
axes[1].plot(df['Month'], df['Profit'], marker='o', linewidth=2, color='#4CAF50')
axes[1].fillbetween(range(len(df)), df['Profit'], alpha=0.3, color='#4CAF50')
axes[1].settitle('Monthly Profit Trend')
axes[1].setylabel('Profit ($)')
plt.tightlayout()
plt.show()
""")
print(execution.text)
Advanced Usage
Integration with OpenAI
Example of building an AI assistant that can execute code:
import openai
from e2bcodeinterpreter import Sandbox
client = openai.OpenAI()
def runaicodeinterpreter(userquery: str) -> str:
"""AI assistant that can write and run code."""
# Step 1: Ask AI to generate code
response = client.chat.completions.create(
model="gpt-4o",
messages=[
{
"role": "system",
"content": (
"You are a data analyst. When asked a question, "
"write Python code to answer it. "
"Only output the Python code, no explanations."
)
},
{"role": "user", "content": userquery}
]
)
code = response.choices[0].message.content
# Clean markdown code blocks if present
code = code.replace("
python", "").replace("``", "").strip()
# Step 2: Run code in E2B sandbox
with Sandbox() as sandbox:
execution = sandbox.runcode(code)
if execution.error:
return f"Error: {execution.error.value}"
return execution.text
Example usage
result = runaicodeinterpreter(
"Calculate the first 20 Fibonacci numbers and show their growth rate"
)
print(result)
Integration with Anthropic Claude
python
import anthropic
from e2bcodeinterpreter import Sandbox
client = anthropic.Anthropic()
tools = [
{
"name": "executepython",
"description": "Execute Python code in a secure sandbox environment",
"inputschema": {
"type": "object",
"properties": {
"code": {
"type": "string",
"description": "Python code to execute"
}
},
"required": ["code"]
}
}
]
def chatwithcodeexecution(usermessage: str):
"""Chat with Claude that can execute code."""
messages = [{"role": "user", "content": usermessage}]
response = client.messages.create(
model="claude-sonnet-4-6",
maxtokens=4096,
tools=tools,
messages=messages
)
# Process tool calls
with Sandbox() as sandbox:
while response.stopreason == "tooluse":
toolresults = []
for block in response.content:
if block.type == "tooluse":
if block.name == "executepython":
execution = sandbox.runcode(block.input["code"])
result = execution.text if not execution.error else f"Error: {execution.error.value}"
toolresults.append({
"type": "toolresult",
"tooluseid": block.id,
"content": result
})
messages.append({"role": "assistant", "content": response.content})
messages.append({"role": "user", "content": toolresults})
response = client.messages.create(
model="claude-sonnet-4-6",
maxtokens=4096,
tools=tools,
messages=messages
)
# Get final text response
for block in response.content:
if hasattr(block, "text"):
return block.text
result = chatwithcodeexecution(
"Analyze the distribution of prime numbers from 1 to 1000. Create a visualization."
)
print(result)
Custom Sandbox Templates
You can create custom templates with pre-installed packages:
bash
Install E2B CLI
npm install -g @e2b/cli
Login
e2b auth login
Initialize a new template
e2b template init --name "data-science-sandbox"
Edit
e2b.Dockerfile:
dockerfile
FROM e2b/code-interpreter:latest
Install additional packages
RUN pip install scikit-learn xgboost lightgbm seaborn plotly
Install system dependencies
RUN apt-get update && apt-get install -y ffmpeg libsm6 libxext6
Build and push the template:
bash
e2b template build
Use the custom template:
python
from e2bcodeinterpreter import Sandbox
Use custom template
with Sandbox(template="data-science-sandbox") as sandbox:
execution = sandbox.runcode("""
import sklearn
import xgboost
print(f"scikit-learn: {sklearn.version}")
print(f"XGBoost: {xgboost.version}")
""")
print(execution.text)
Streaming Output
For long-running code, use streaming to get output in real-time:
python
from e2bcodeinterpreter import Sandbox
with Sandbox() as sandbox:
execution = sandbox.runcode(
"""
import time
for i in range(10):
print(f"Processing step {i+1}/10...")
time.sleep(1)
print("Done!")
""",
onstdout=lambda output: print(f"[STDOUT] {output.line}"),
onstderr=lambda output: print(f"[STDERR] {output.line}")
)
Timeout and Resource Management
python
from e2bcodeinterpreter import Sandbox
Sandbox with custom timeout (in seconds)
with Sandbox(timeout=300) as sandbox: # 5 minute timeout
execution = sandbox.runcode(
"""
import time
Long-running process
time.sleep(10)
print("Long process completed!")
""",
timeout=60 # Per-execution timeout: 60 seconds
)
print(execution.text)
Installing Packages at Runtime
python
from e2bcodeinterpreter import Sandbox
with Sandbox() as sandbox:
# Install packages using pip
sandbox.runcode("!pip install requests beautifulsoup4")
# Use the newly installed packages
execution = sandbox.runcode("""
import requests
from bs4 import BeautifulSoup
response = requests.get('https://httpbin.org/json')
data = response.json()
print(f"Status: {response.statuscode}")
print(f"Data: {data}")
""")
print(execution.text)
Building a Data Analysis Agent
Here's a complete example of building a data analysis agent using E2B:
python
from e2bcodeinterpreter import Sandbox
import json
class DataAnalysisAgent:
def init(self):
self.sandbox = Sandbox()
self.setupenvironment()
def setupenvironment(self):
"""Set up the environment with required libraries."""
self.sandbox.runcode("""
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import warnings
warnings.filterwarnings('ignore')
plt.style.use('seaborn-v08-whitegrid')
print("Environment ready!")
""")
def loadcsv(self, csvcontent: str, filename: str = "data.csv"):
"""Load CSV data into the sandbox."""
self.sandbox.files.write(f"/home/user/{filename}", csvcontent.encode())
execution = self.sandbox.runcode(f"""
df = pd.readcsv('/home/user/{filename}')
print(f"Loaded {{len(df)}} rows, {{len(df.columns)}} columns")
print(f"Columns: {{list(df.columns)}}")
print()
print(df.head())
""")
return execution.text
def analyze(self, question: str):
"""Run analysis based on a question."""
execution = self.sandbox.runcode(f"""
Analysis: {question}
print("=== Data Overview ===")
print(f"Shape: {{df.shape}}")
print()
print("=== Statistical Summary ===")
print(df.describe())
print()
print("=== Missing Values ===")
print(df.isnull().sum())
""")
return execution.text
def createchart(self, chartcode: str):
"""Generate a chart in the sandbox."""
execution = self.sandbox.runcode(chartcode)
results = []
for result in execution.results:
if hasattr(result, 'png'):
results.append(result.png)
return results
def close(self):
"""Close the sandbox."""
self.sandbox.close()
Example usage
agent = DataAnalysisAgent()
Load data
csvdata = """name,age,salary,department
Alice,30,75000,Engineering
Bob,25,55000,Marketing
Charlie,35,90000,Engineering
Diana,28,62000,Sales
Eve,32,85000,Engineering
Frank,27,58000,Marketing
"""
print(agent.loadcsv(csvdata))
print(agent.analyze("What is the salary distribution?"))
agent.close()
Best Practices
1. Always Use Context Managers
python
Good - sandbox is automatically closed
with Sandbox() as sandbox:
sandbox.runcode("print('hello')")
Not ideal - you might forget to close the sandbox
sandbox = Sandbox()
sandbox.runcode("print('hello')")
sandbox.close() # Don't forget!
2. Handle Errors Gracefully
python
from e2bcodeinterpreter import Sandbox
with Sandbox() as sandbox:
execution = sandbox.runcode(usercode)
if execution.error:
# Log the error for debugging
print(f"Execution failed: {execution.error.name}")
print(f"Message: {execution.error.value}")
# Don't expose full traceback to end users
else:
# Process results
processoutput(execution.text)
3. Set Timeouts for User Code
python
with Sandbox() as sandbox:
# Don't let user code run indefinitely
execution = sandbox.runcode(
untrustedcode,
timeout=30 # Maximum 30 seconds
)
4. Validate Input Before Execution
python
import re
FORBIDDENPATTERNS = [
r'os\.system',
r'subprocess',
r'shutil\.rmtree',
r'open\(./etc/',
]
def validatecode(code: str) -> bool:
"""Validate code before executing in the sandbox."""
for pattern in FORBIDDENPATTERNS:
if re.search(pattern, code):
return False
return True
with Sandbox() as sandbox:
if validatecode(usercode):
execution = sandbox.runcode(usercode)
else:
print("Code contains forbidden patterns")
5. Use Custom Templates for Production
For production environments, create custom templates so you don't need to install packages every time you create a new sandbox. This saves startup time and costs.
6. Monitor Resource Usage
python
with Sandbox() as sandbox:
execution = sandbox.runcode("""
import psutil
import os
Check memory usage
memory = psutil.virtualmemory()
print(f"Total Memory: {memory.total / (10243):.1f} GB")
print(f"Available: {memory.available / (10243):.1f} GB")
print(f"Used: {memory.percent}%")
Check disk usage
disk = psutil.diskusage('/')
print(f"\\nDisk Total: {disk.total / (10243):.1f} GB")
print(f"Disk Used: {disk.used / (10243):.1f} GB")
print(f"Disk Free: {disk.free / (10243):.1f} GB")
""")
print(execution.text)
``
Comparison with Alternatives
| Feature | E2B | Modal | Docker | AWS Lambda |
|---------|-----|-------|--------|------------|
| Startup time | ~150ms | ~1s | ~2-5s | ~100-500ms |
| Sandbox isolation | MicroVM | Container | Container | Firecracker |
| Pre-installed packages | Python + DS libs | Custom | Custom | Layer-based |
| File I/O | Yes | Yes | Yes | Limited |
| Visualization support | Built-in | Manual | Manual | No |
| Pricing model | Per sandbox/min | Per compute | Self-hosted | Per request |
| AI SDK integration | Native | SDK | Manual | Manual |
Conclusion
E2B Code Interpreter is an excellent solution for building AI applications that require secure code execution. With microVM-based sandboxes, you get strong isolation without sacrificing speed. Native integration with various LLM providers makes it ideal for building AI agents, code interpreters, and data analysis tools.
Key takeaways:
With this guide, you're ready to build AI applications that can execute code safely and efficiently using E2B Code Interpreter.