Overview

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 += 1

Ask 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.

Next#

Was this page helpful?