Skip to main content

Overview

The Code Interpreter provides a high-level API for running Python, JavaScript, and TypeScript code with structured execution contexts. It’s designed for:
  • Interactive code execution (REPL-like)
  • Notebook-style workflows
  • Data science and ML tasks
  • Dynamic code evaluation
Unlike raw command execution, the interpreter manages execution contexts, captures rich results (text, charts, errors), and provides structured output.

Quick start

import { getSandbox } from '@cloudflare/sandbox';

const sandbox = getSandbox(env.SANDBOX, 'ml-project');

// Run Python code
const execution = await sandbox.runCode(`
import numpy as np
import matplotlib.pyplot as plt

x = np.linspace(0, 10, 100)
y = np.sin(x)

plt.plot(x, y)
plt.title('Sine Wave')
plt.savefig('output.png')

print(f'Generated {len(x)} points')
`, {
  language: 'python'
});

// Access results
console.log('stdout:', execution.logs.stdout);
if (execution.error) {
  console.error('Error:', execution.error.message);
}

Execution contexts

Contexts maintain state across multiple code executions:
// Create a context
const context = await sandbox.createCodeContext({
  language: 'python',
  cwd: '/workspace/notebooks'
});

// Run code in the context
const exec1 = await sandbox.runCode('x = 42', {
  context,
  language: 'python'
});

const exec2 = await sandbox.runCode('print(x)', {
  context,
  language: 'python'
});
// Output: 42 (variable persists)

Context lifecycle

// List all contexts
const contexts = await sandbox.listCodeContexts();

for (const ctx of contexts) {
  console.log(`Context ${ctx.id}: ${ctx.language}`);
}

// Delete a context
await sandbox.deleteCodeContext(context.id);

Supported languages

Python

Python 3.11 with pre-installed libraries:
const execution = await sandbox.runCode(`
import pandas as pd
import numpy as np
from sklearn.linear_model import LinearRegression

# Your data science code here
df = pd.DataFrame({'x': [1, 2, 3], 'y': [2, 4, 6]})
print(df.describe())
`, {
  language: 'python'
});
Available packages:
  • numpy - Numerical computing
  • pandas - Data manipulation
  • matplotlib - Plotting and visualization
  • ipython - Interactive Python features
  • Standard library (requests, json, etc.)

JavaScript

Node.js 20 LTS runtime:
const execution = await sandbox.runCode(`
const data = [1, 2, 3, 4, 5];
const sum = data.reduce((a, b) => a + b, 0);
console.log('Sum:', sum);
`, {
  language: 'javascript'
});

TypeScript

TypeScript with automatic transpilation:
const execution = await sandbox.runCode(`
interface Point {
  x: number;
  y: number;
}

const p: Point = { x: 10, y: 20 };
console.log('Point:', p);
`, {
  language: 'typescript'
});

Execution results

The Execution object provides structured access to results:
interface Execution {
  code: string;              // Code that was executed
  context: CodeContext;      // Execution context
  results: Result[];         // Structured results (text, charts, etc.)
  logs: {
    stdout: string[];        // Standard output lines
    stderr: string[];        // Standard error lines
  };
  error?: ExecutionError;    // Error if execution failed
}

Result types

Execution can produce multiple types of results:
interface Result {
  type: 'text' | 'image' | 'chart' | 'html' | 'json';
  data: any;               // Result data (format depends on type)
  metadata?: Record<string, any>;
}
Example with multiple results:
const execution = await sandbox.runCode(`
import matplotlib.pyplot as plt
import json

# Generate a chart
plt.plot([1, 2, 3], [1, 4, 9])
plt.savefig('chart.png')

# Output JSON
data = {'status': 'success', 'points': 3}
print(json.dumps(data))

# Regular output
print('Computation complete')
`, {
  language: 'python'
});

// Access different result types
for (const result of execution.results) {
  if (result.type === 'image') {
    console.log('Chart saved:', result.data);
  } else if (result.type === 'json') {
    console.log('JSON result:', result.data);
  }
}

// Access logs
console.log('Output:', execution.logs.stdout.join('\n'));

Streaming execution

For long-running code, stream results as they’re generated:
const stream = await sandbox.runCodeStream(`
import time

for i in range(10):
    print(f'Step {i}')
    time.sleep(1)
`, {
  language: 'python'
});

// Parse SSE stream
for await (const event of parseSSEStream(stream)) {
  if (event.type === 'stdout') {
    console.log('Output:', event.data);
  } else if (event.type === 'result') {
    console.log('Result:', event.data);
  } else if (event.type === 'error') {
    console.error('Error:', event.data);
  }
}

Stream callbacks

Use callbacks for easier streaming:
const execution = await sandbox.runCode(code, {
  language: 'python',
  onStdout: (output) => {
    console.log('OUT:', output.text);
  },
  onStderr: (output) => {
    console.error('ERR:', output.text);
  },
  onResult: (result) => {
    if (result.type === 'image') {
      console.log('Image generated:', result.data);
    }
  },
  onError: (error) => {
    console.error('Execution failed:', error.message);
  }
});

Error handling

Execution errors are captured in the result:
const execution = await sandbox.runCode(`
import non_existent_module
`, {
  language: 'python'
});

if (execution.error) {
  console.error('Error:', execution.error.message);
  console.error('Traceback:', execution.error.traceback);
  console.error('Type:', execution.error.type); // e.g., 'ModuleNotFoundError'
}
interface ExecutionError {
  message: string;          // Error message
  type: string;            // Error type (e.g., 'SyntaxError')
  traceback?: string;      // Stack trace (Python) or stack (JavaScript)
  line?: number;           // Line number where error occurred
}

Common patterns

Data analysis workflow

// Create context for data analysis
const context = await sandbox.createCodeContext({
  language: 'python',
  cwd: '/workspace/data'
});

// Load data
await sandbox.runCode(`
import pandas as pd
df = pd.read_csv('input.csv')
print(f'Loaded {len(df)} rows')
`, { context });

// Process data
await sandbox.runCode(`
df['normalized'] = (df['value'] - df['value'].mean()) / df['value'].std()
df.to_csv('output.csv', index=False)
`, { context });

// Visualize
await sandbox.runCode(`
import matplotlib.pyplot as plt
plt.hist(df['normalized'], bins=30)
plt.savefig('distribution.png')
`, { context });

// Download results
const result = await sandbox.readFile('/workspace/data/output.csv');

Interactive notebook

// Create persistent context
const notebook = await sandbox.createCodeContext({
  language: 'python'
});

// Execute cells
const cells = [
  'import numpy as np',
  'x = np.array([1, 2, 3, 4, 5])',
  'mean = x.mean()',
  'print(f"Mean: {mean}")'
];

for (const cell of cells) {
  const exec = await sandbox.runCode(cell, { context: notebook });
  console.log('Cell output:', exec.logs.stdout);
}

Safe code evaluation

try {
  const execution = await sandbox.runCode(userCode, {
    language: 'python',
    timeout: 30000  // 30 second limit
  });
  
  if (execution.error) {
    return Response.json({
      success: false,
      error: execution.error.message
    });
  }
  
  return Response.json({
    success: true,
    output: execution.logs.stdout,
    results: execution.results
  });
} catch (error) {
  // Timeout or other errors
  return Response.json({
    success: false,
    error: 'Execution timed out or failed'
  }, { status: 500 });
}

Architecture

The Code Interpreter is built on top of the sandbox’s command execution:
CodeInterpreter.runCode()

InterpreterClient.runCodeStream()

HTTP POST /api/interpreter/run

Container Interpreter Service

Language Runtime (Python/Node.js)

Structured Results
Key components:
  • CodeInterpreter: High-level SDK class
  • InterpreterClient: HTTP client for interpreter API
  • Container Service: Manages language runtimes and contexts
  • Result Parser: Extracts structured outputs from execution

Context vs session

Code contexts are different from execution sessions:
FeatureCode ContextExecution Session
PurposeCode state (variables, imports)Shell state (cwd, env)
Language-specificYesNo
IsolationPer-contextPer-session
Use caseREPL, notebooksCommand execution
You can use both together:
// Create session
const session = await sandbox.createSession({
  cwd: '/workspace/ml'
});

// Create code context in that session
const context = await session.createCodeContext({
  language: 'python'
});

// Run code in both contexts
await session.runCode('import numpy as np', { context });

Limitations

  • Package installation: Pre-installed packages only (cannot pip install at runtime)
  • Output size: Large outputs may be truncated
  • Execution time: Consider timeouts for long-running code
  • Concurrency: Multiple contexts can run in parallel but share container resources
For custom package requirements, use exec() with pip install or modify the container Dockerfile.

Build docs developers (and LLMs) love