Analyze data with AI
1
Install
npm i @e2b/code-interpreter @anthropic-ai/sdk dotenv or pip install e2b-code-interpreter anthropic python-dotenv. Set E2B_API_KEY and ANTHROPIC_API_KEY in .env.
2
Upload the dataset
Write the CSV into the sandbox and keep the path it returns — the prompt needs it.
3
Give the model a tool
Declare a run_python_code tool with a single code string, describe the columns, and ask for the chart.
4
Run what it wrote
For every tool_use block, pass input.code to sbx.runCode() / sbx.run_code().
5
Save the charts
Every result with a png field is a base64-encoded image.
Run the generated code and save charts#
import fs from 'fs'
import { Sandbox } from '@e2b/code-interpreter'
const sbx = await Sandbox.create()
const dataset = await sbx.files.write('/home/user/dataset.csv', fs.readFileSync('dataset.csv'))
async function runAIGeneratedCode(code: string) {
const execution = await sbx.runCode(code)
if (execution.error) {
console.error(execution.error.name, execution.error.value)
console.log(execution.error.traceback)
return
}
let i = 0
for (const result of execution.results) {
if (result.png) {
fs.writeFileSync(`chart-${i++}.png`, result.png, { encoding: 'base64' })
}
}
}import base64
from e2b_code_interpreter import Sandbox
sbx = Sandbox.create()
with open("dataset.csv", "rb") as f:
dataset = sbx.files.write("dataset.csv", f)
def run_ai_generated_code(code: str):
execution = sbx.run_code(code)
if execution.error:
print(execution.error.name, execution.error.value)
print(execution.error.traceback)
return
i = 0
for result in execution.results:
if result.png:
with open(f"chart-{i}.png", "wb") as f:
f.write(base64.b64decode(result.png))
i += 1Ask Claude for the code#
import Anthropic from '@anthropic-ai/sdk'
const msg = await new Anthropic().messages.create({
model: 'claude-haiku-4-5-20251001',
max_tokens: 1024,
messages: [{ role: 'user', content: `The CSV is at ${dataset.path}. Columns: ... Plot vote_average over the years. End with display(plt.gcf())` }],
tools: [{
name: 'run_python_code',
description: 'Run Python code',
input_schema: {
type: 'object',
properties: { code: { type: 'string', description: 'The Python code to run' } },
required: ['code'],
},
}],
})
for (const block of msg.content) {
if (block.type === 'tool_use' && block.name === 'run_python_code') {
await runAIGeneratedCode((block.input as { code: string }).code)
}
}from anthropic import Anthropic
msg = Anthropic().messages.create(
model="claude-haiku-4-5-20251001",
max_tokens=1024,
messages=[{"role": "user", "content": f"The CSV is at {dataset.path}. Columns: ... Plot vote_average over the years. End with display(plt.gcf())"}],
tools=[{
"name": "run_python_code",
"description": "Run Python code",
"input_schema": {
"type": "object",
"properties": {"code": {"type": "string", "description": "The Python code to run"}},
"required": ["code"],
},
}],
)
for block in msg.content:
if block.type == "tool_use" and block.name == "run_python_code":
run_ai_generated_code(block.input["code"])Tell the model to end its code with display(plt.gcf()) — that is what makes the chart come back as a png result instead of staying inside the sandbox.