Skip to main content
The Code Interpreter provides advanced Python code execution capabilities with context isolation, streaming output, and comprehensive error handling.

Overview

Daytona’s Code Interpreter enables:
  • Stateful execution - Maintain variables and state between executions
  • Context isolation - Run code in isolated interpreter contexts
  • Real-time streaming - Stream stdout/stderr as code executes
  • Error tracking - Detailed error information with tracebacks
For other languages (TypeScript, JavaScript), use sandbox.process.codeRun() instead. See Process Execution for details.

Basic Execution

Simple Code Execution

Execute Python code and get results:
const result = await sandbox.codeInterpreter.runCode(`
print("Hello from Python!")
x = 10
y = 20
print(f"Sum: {x + y}")
`);

console.log(result.stdout);
// Output:
// Hello from Python!
// Sum: 30

Execution with Timeout

Set a timeout to prevent long-running code:
try {
  const result = await sandbox.codeInterpreter.runCode(
    `
import time
print('Starting...')
time.sleep(10)
print('Done!')
    `,
    { timeout: 5 }  // 5 seconds
  );
} catch (error) {
  if (error instanceof DaytonaTimeoutError) {
    console.log('Execution timed out');
  }
}
code
string
required
Python code to execute
options
RunCodeOptions
Execution options

Stateful Execution

Default Context State

Variables persist between executions in the default context:
// First execution
const result1 = await sandbox.codeInterpreter.runCode(`
counter = 1
print(f'Initialized counter = {counter}')
`);

console.log(result1.stdout); // Initialized counter = 1

// Second execution - counter still exists
const result2 = await sandbox.codeInterpreter.runCode(`
counter += 1
print(f'Counter after increment = {counter}')
`);

console.log(result2.stdout); // Counter after increment = 2

Context Isolation

Create Isolated Context

Create separate contexts for isolated execution:
const ctx = await sandbox.codeInterpreter.createContext();

try {
  // Execute in isolated context
  const result = await sandbox.codeInterpreter.runCode(
    `
value = 'stored in isolated context'
print(f'Isolated value: {value}')
    `,
    { context: ctx }
  );
  
  console.log(result.stdout);
  // Output: Isolated value: stored in isolated context
  
  // Variable persists in same context
  const result2 = await sandbox.codeInterpreter.runCode(
    "print(f'Value still available: {value}')",
    { context: ctx }
  );
  
  console.log(result2.stdout);
  // Output: Value still available: stored in isolated context
  
  // Variable NOT available in default context
  const result3 = await sandbox.codeInterpreter.runCode(
    'print(value)'
    // No context = default context
  );
  
  // This will error: NameError: name 'value' is not defined
  
} finally {
  // Clean up context when done
  await sandbox.codeInterpreter.deleteContext(ctx);
}

Context with Working Directory

const ctx = await sandbox.codeInterpreter.createContext(
  '/workspace/project'
);

try {
  const result = await sandbox.codeInterpreter.runCode(
    `
import os
print(f'Working directory: {os.getcwd()}')
    `,
    { context: ctx }
  );
  
  console.log(result.stdout);
  // Output: Working directory: /workspace/project
  
} finally {
  await sandbox.codeInterpreter.deleteContext(ctx);
}

List Active Contexts

const contexts = await sandbox.codeInterpreter.listContexts();

contexts.forEach(ctx => {
  console.log('Context ID:', ctx.id);
  console.log('Language:', ctx.language);
  console.log('Working Directory:', ctx.cwd);
});
cwd
string
Working directory for the context. Uses sandbox working directory if omitted.

Streaming Output

Real-time Output Streaming

Stream output as code executes:
const handleStdout = (msg: OutputMessage) => {
  process.stdout.write(`[STDOUT] ${msg.output}`);
};

const handleStderr = (msg: OutputMessage) => {
  process.stderr.write(`[STDERR] ${msg.output}`);
};

const handleError = (err: ExecutionError) => {
  console.error(`[ERROR] ${err.name}: ${err.value}`);
  if (err.traceback) {
    console.error(err.traceback);
  }
};

const result = await sandbox.codeInterpreter.runCode(
  `
import time
for i in range(5):
    print(f'Count: {i}')
    time.sleep(1)
  `,
  {
    onStdout: handleStdout,
    onStderr: handleStderr,
    onError: handleError,
    timeout: 10
  }
);

Error Handling

Capture Execution Errors

const result = await sandbox.codeInterpreter.runCode(
  `
x = 10
y = 0
result = x / y  # Division by zero
  `,
  {
    onError: (err) => {
      console.log('Error name:', err.name);        // ZeroDivisionError
      console.log('Error value:', err.value);      // division by zero
      console.log('Traceback:', err.traceback);    // Full traceback
    }
  }
);

if (result.error) {
  console.log('Execution failed with error:', result.error.name);
}
Error Response:
interface ExecutionError {
  name: string;       // Error type (ValueError, TypeError, etc.)
  value: string;      // Error message
  traceback?: string; // Full traceback
}

Environment Variables

const result = await sandbox.codeInterpreter.runCode(
  `
import os
print(f"API Key: {os.environ.get('API_KEY')}")
print(f"Debug Mode: {os.environ.get('DEBUG')}")
  `,
  {
    envs: {
      API_KEY: 'secret-key-123',
      DEBUG: 'true'
    }
  }
);

Complete Example

import {
  Daytona,
  DaytonaTimeoutError,
  ExecutionError,
  OutputMessage
} from '@daytonaio/sdk';

const daytona = new Daytona();
const sandbox = await daytona.create();

try {
  // Create isolated context
  const ctx = await sandbox.codeInterpreter.createContext(
    '/workspace'
  );
  
  try {
    console.log('=== Loading Data ===');
    
    // Load data in context
    const loadResult = await sandbox.codeInterpreter.runCode(
      `
import json

data = {
    'users': [
        {'name': 'Alice', 'age': 30},
        {'name': 'Bob', 'age': 25}
    ]
}

print(f'Loaded {len(data["users"])} users')
      `,
      {
        context: ctx,
        onStdout: (msg) => console.log(msg.output)
      }
    );
    
    console.log('\n=== Processing Data ===');
    
    // Process data in same context
    const processResult = await sandbox.codeInterpreter.runCode(
      `
for user in data['users']:
    print(f"{user['name']} is {user['age']} years old")

avg_age = sum(u['age'] for u in data['users']) / len(data['users'])
print(f"\nAverage age: {avg_age}")
      `,
      {
        context: ctx,
        onStdout: (msg) => console.log(msg.output),
        onError: (err) => {
          console.error(`Error: ${err.name}: ${err.value}`);
          if (err.traceback) console.error(err.traceback);
        }
      }
    );
    
    // Check for errors
    if (processResult.error) {
      console.error('Processing failed!');
    } else {
      console.log('\nProcessing completed successfully');
    }
    
  } finally {
    // Always clean up context
    await sandbox.codeInterpreter.deleteContext(ctx);
  }
  
} catch (error) {
  if (error instanceof DaytonaTimeoutError) {
    console.error('Execution timed out');
  } else {
    console.error('Execution failed:', error);
  }
} finally {
  await daytona.delete(sandbox);
}

Best Practices

Create separate contexts for unrelated execution tasks to prevent variable conflicts:
const ctx1 = await sandbox.codeInterpreter.createContext();
const ctx2 = await sandbox.codeInterpreter.createContext();

// Run independent tasks
await sandbox.codeInterpreter.runCode(code1, { context: ctx1 });
await sandbox.codeInterpreter.runCode(code2, { context: ctx2 });
Delete contexts when finished to free resources:
const ctx = await sandbox.codeInterpreter.createContext();
try {
  // Use context
} finally {
  await sandbox.codeInterpreter.deleteContext(ctx);
}
Always set timeouts to prevent runaway code execution:
await sandbox.codeInterpreter.runCode(code, {
  timeout: 60  // 60 seconds max
});
For long-running code, use callbacks to monitor progress:
await sandbox.codeInterpreter.runCode(code, {
  onStdout: (msg) => console.log('Progress:', msg.output),
  timeout: 300
});

Execution Response

interface ExecutionResult {
  stdout: string;           // Standard output
  stderr: string;           // Standard error
  error?: ExecutionError;   // Error details if execution failed
}

Limitations

The Code Interpreter currently only supports Python. For TypeScript and JavaScript code execution, use sandbox.process.codeRun() instead.
Default timeout is 10 minutes. Set timeout: 0 for no timeout, but be cautious of infinite loops.

Process Execution

Execute code in other languages (TypeScript, JavaScript)

PTY Sessions

Interactive terminal sessions for Python REPL

Build docs developers (and LLMs) love