# Source: https://www.daytona.io/docs/en/process-code-execution.md

The Daytona SDK provides powerful process and code execution capabilities through the `process` module in Sandboxes. This guide covers all available process operations and best practices.

## Code Execution

Daytona SDK supports both stateless and stateful code execution flows. Stateless runs use the `process` module and
supports multiple languages (Python, TypeScript, JavaScript). The stateful code interpreter keeps variables and imports
between calls and currently supports only Python.

:::note

- Stateless execution inherits the Sandbox language that you choose at creation time. See [Basic Sandbox Creation](https://www.daytona.io/docs/en/sandboxes.md#basic-sandbox-creation).
- The stateful interpreter supports only Python.
  :::

### Stateless Execution

Use stateless execution when each snippet is independent. Every invocation starts from a clean interpreter.

```python
# Run Python code
response = sandbox.process.code_run('''
def greet(name):
    return f"Hello, {name}!"

print(greet("Daytona"))
''')

print(response.result)
```
```typescript
// Run TypeScript code
let response = await sandbox.process.codeRun(`
function greet(name: string): string {
    return \`Hello, \${name}!\`;
}

console.log(greet("Daytona"));
`);
console.log(response.result);

// Run code with argv and environment variables
response = await sandbox.process.codeRun(
    `
    console.log(\`Hello, \${process.argv[2]}!\`);
    console.log(\`FOO: \${process.env.FOO}\`);
    `,
    { 
      argv: ["Daytona"],
      env: { FOO: "BAR" }
    }
);
console.log(response.result);

// Run code with timeout
response = await sandbox.process.codeRun(
    'setTimeout(() => console.log("Done"), 2000);',
    undefined,
    5000
);
console.log(response.result);
```

```ruby
# Run Python code
response = sandbox.process.code_run(code: <<~PYTHON)
  def greet(name):
      return f"Hello, {name}!"
  
  print(greet("Daytona"))
PYTHON

puts response.result

# Run code with environment variables
response = sandbox.process.code_run(
  code: 'import os; print(f"FOO: {os.environ.get(\'FOO\')}")',
  env: { 'FOO' => 'BAR' }
)
puts response.result

# Run code with timeout
response = sandbox.process.code_run(
  code: 'import time; time.sleep(2); print("Done")',
  timeout: 5
)
puts response.result
```

See: [code_run (Python SDK)](https://www.daytona.io/docs/python-sdk/sync/process.md#processcode_run), [codeRun (TypeScript SDK)](https://www.daytona.io/docs/typescript-sdk/process.md#coderun), [code_run (Ruby SDK)](https://www.daytona.io/docs/ruby-sdk/process.md#code_run)

### Stateful Code Interpreter

When you need to persist variables, imports between calls, use the Sandbox code interpreter. It offers:

- A shared default context that keeps state between calls.
- The ability to create/delete isolated contexts for specific workflows.
- Per-call environment variables and timeout controls.

```python
from daytona import Daytona, OutputMessage

def handle_stdout(message: OutputMessage):
    print(f"[STDOUT] {message.output}")

daytona = Daytona()
sandbox = daytona.create()

# Shared default context
result = sandbox.code_interpreter.run_code(
    "counter = 1\nprint(f'Counter initialized at {counter}')",
    on_stdout=handle_stdout,
)

# Isolated context
ctx = sandbox.code_interpreter.create_context()
try:
    sandbox.code_interpreter.run_code(
        "value = 'stored in ctx'",
        context=ctx,
    )
    sandbox.code_interpreter.run_code(
        "print(value)",
        context=ctx,
        on_stdout=handle_stdout,
    )
finally:
    sandbox.code_interpreter.delete_context(ctx)
```
```typescript
import { Daytona } from '@daytonaio/sdk'

const daytona = new Daytona()

async function main() {
    const sandbox = await daytona.create()

    // Shared default context
    await sandbox.codeInterpreter.runCode(
`
counter = 1
print(f'Counter initialized at {counter}')
`,
        { onStdout: (msg) => process.stdout.write(`[STDOUT] ${msg.output}`)},
    )

    // Isolated context
    const ctx = await sandbox.codeInterpreter.createContext()
    try {
    await sandbox.codeInterpreter.runCode(
        `value = 'stored in ctx'`,
        { context: ctx },
    )
    await sandbox.codeInterpreter.runCode(
        `print(value)`,
        { context: ctx, onStdout: (msg) => process.stdout.write(`[STDOUT] ${msg.output}`) },
    )
    } finally {
    await sandbox.codeInterpreter.deleteContext(ctx)
    }
}

main()
```

See: [code_interpreter (Python SDK)](https://www.daytona.io/docs/python-sdk/sync/code-interpreter.md), [codeInterpreter (TypeScript SDK)](https://www.daytona.io/docs/typescript-sdk/code-interpreter.md), and [code_interpreter (Ruby SDK)](https://www.daytona.io/docs/ruby-sdk/code-interpreter.md)

## Process Execution

Daytona SDK provides an option to execute shell commands and manage background processes in Sandboxes. The workDir for executing defaults to the current Sandbox working directory. Uses the WORKDIR specified in
the Dockerfile if present, or falling back to the user's home directory if not - e.g. `workspace/repo` implies `/my-work-dir/workspace/repo`, but you can override it with an absolute path (by starting the path with `/`).

### Running Commands

Daytona SDK provides an option to execute shell commands in Python, TypeScript, and Ruby. You can run commands with input, timeout, and environment variables.

```python
# Execute any shell command
response = sandbox.process.exec("ls -la")
print(response.result)

# Setting a working directory and a timeout

response = sandbox.process.exec("sleep 3", cwd="workspace/src", timeout=5)
print(response.result)

# Passing environment variables

response = sandbox.process.exec("echo $CUSTOM_SECRET", env={
        "CUSTOM_SECRET": "DAYTONA"
    }
)
print(response.result)

```
```typescript

// Execute any shell command
const response = await sandbox.process.executeCommand("ls -la");
console.log(response.result);

// Setting a working directory and a timeout
const response2 = await sandbox.process.executeCommand("sleep 3", "workspace/src", undefined, 5);
console.log(response2.result);

// Passing environment variables
const response3 = await sandbox.process.executeCommand("echo $CUSTOM_SECRET", ".", {
        "CUSTOM_SECRET": "DAYTONA"
    }
);
console.log(response3.result);

```


```ruby

# Execute any shell command
response = sandbox.process.exec(command: 'ls -la')
puts response.result

# Setting a working directory and a timeout
response = sandbox.process.exec(command: 'sleep 3', cwd: 'workspace/src', timeout: 5)
puts response.result

# Passing environment variables
response = sandbox.process.exec(
  command: 'echo $CUSTOM_SECRET',
  env: { 'CUSTOM_SECRET' => 'DAYTONA' }
)
puts response.result

```


See: [exec (Python SDK)](https://www.daytona.io/docs/python-sdk/sync/process.md#processexec), [executeCommand (TypeScript SDK)](https://www.daytona.io/docs/typescript-sdk/process.md#executecommand), [exec (Ruby SDK)](https://www.daytona.io/docs/ruby-sdk/process.md#exec)

## Sessions (Background Processes)

Daytona SDK provides an option to start, stop, and manage background process sessions in Sandboxes. You can run long-running commands, monitor process status, and list all running processes.

### Managing Long-Running Processes

Daytona SDK provides an option to start and stop background processes. You can run long-running commands and monitor process status.

```python
# Check session's executed commands
session = sandbox.process.get_session(session_id)
print(f"Session {process_id}:")
for command in session.commands:
    print(f"Command: {command.command}, Exit Code: {command.exit_code}")

# List all running sessions

sessions = sandbox.process.list_sessions()
for session in sessions:
    print(f"PID: {session.id}, Commands: {session.commands}")

```
```typescript
// Check session's executed commands
const session = await sandbox.process.getSession(sessionId);
console.log(`Session ${sessionId}:`);
for (const command of session.commands) {
    console.log(`Command: ${command.command}, Exit Code: ${command.exitCode}`);
}

// List all running sessions
const sessions = await sandbox.process.listSessions();
for (const session of sessions) {
    console.log(`PID: ${session.id}, Commands: ${session.commands}`);
}

```


```ruby
# Check session's executed commands
session = sandbox.process.get_session(session_id)
puts "Session #{session_id}:"
session.commands.each do |command|
  puts "Command: #{command.command}, Exit Code: #{command.exit_code}"
end

# List all running sessions
sessions = sandbox.process.list_sessions
sessions.each do |session|
  puts "PID: #{session.id}, Commands: #{session.commands}"
end

```


See: [get_session (Python SDK)](https://www.daytona.io/docs/python-sdk/sync/process.md#processget_session), [list_sessions (Python SDK)](https://www.daytona.io/docs/python-sdk/sync/process.md#processlist_sessions), [getSession (TypeScript SDK)](https://www.daytona.io/docs/typescript-sdk/process.md#getsession), [listSessions (TypeScript SDK)](https://www.daytona.io/docs/typescript-sdk/process.md#listsessions), [get_session (Ruby SDK)](https://www.daytona.io/docs/ruby-sdk/process.md#get_session), [list_sessions (Ruby SDK)](https://www.daytona.io/docs/ruby-sdk/process.md#list_sessions)

### Interactive Session Commands

Session commands can be interactive, allowing you to send input to running commands that expect user interaction,
such as confirmations or interactive tools (e.g., database CLIs or package managers).

```python
session_id = "interactive-session"
sandbox.process.create_session(session_id)

# Execute command that requires confirmation
command = sandbox.process.execute_session_command(
    session_id,
    SessionExecuteRequest(
        command='pip uninstall requests',
        run_async=True,
    ),
)

# Stream logs asynchronously
logs_task = asyncio.create_task(
    sandbox.process.get_session_command_logs_async(
        session_id,
        command.cmd_id,
        lambda log: print(f"[STDOUT]: {log}"),
        lambda log: print(f"[STDERR]: {log}"),
    )
)

await asyncio.sleep(1)
# Send input to the command
sandbox.process.send_session_command_input(session_id, command.cmd_id, "y")

# Wait for logs to complete
await logs_task
```
```typescript
const sessionId = 'interactive-session'
await sandbox.process.createSession(sessionId)

// Execute command that requires confirmation
const command = await sandbox.process.executeSessionCommand(sessionId, {
    command: 'pip uninstall requests',
    runAsync: true,
})

// Stream logs asynchronously
const logPromise = sandbox.process.getSessionCommandLogs(
    sessionId,
    command.cmdId!,
    (stdout) => console.log('[STDOUT]:', stdout),
    (stderr) => console.log('[STDERR]:', stderr),
)

await new Promise((resolve) => setTimeout(resolve, 1000))
// Send input to the command
await sandbox.process.sendSessionCommandInput(sessionId, command.cmdId!, 'y')

// Wait for logs to complete
await logPromise
```
```ruby
session_id = "interactive-session"
sandbox.process.create_session(session_id)

# Execute command that requires confirmation
interactive_command = sandbox.process.execute_session_command(
  session_id: session_id,
  req: Daytona::SessionExecuteRequest.new(
    command: 'pip uninstall requests',
    run_async: true
  )
)

# Wait a moment for the command to start
sleep 1

# Send input to the command
sandbox.process.send_session_command_input(
  session_id: session_id,
  command_id: interactive_command.cmd_id,
  data: "y"
)

# Get logs for the interactive command asynchronously
sandbox.process.get_session_command_logs_async(
  session_id: session_id,
  command_id: interactive_command.cmd_id,
  on_stdout: ->(log) { puts "[STDOUT]: #{log}" },
  on_stderr: ->(log) { puts "[STDERR]: #{log}" }
)
```

See: [send_session_command_input (Python SDK)](https://www.daytona.io/docs/python-sdk/sync/process.md#processsend_session_command_input), [sendSessionCommandInput (TypeScript SDK)](https://www.daytona.io/docs/typescript-sdk/process.md#sendsessioncommandinput)

## Best Practices

Use the following best practices when working with process and code execution in Daytona SDK.

### Resource Management

The following best practices apply to managing resources when executing processes:

1. Use [sessions](#sessions-background-processes) for long-running operations
2. Clean up sessions after execution
3. Handle session exceptions properly

   ```python
   # Python - Clean up session
   session_id = "long-running-cmd"
   try:
       sandbox.process.create_session(session_id)
       session = sandbox.process.get_session(session_id)
       # Do work...
   finally:
       sandbox.process.delete_session(session.session_id)
   ```
   ```typescript
   // TypeScript - Clean up session
   const sessionId = "long-running-cmd";
   try {
       await sandbox.process.createSession(sessionId);
       const session = await sandbox.process.getSession(sessionId);
       // Do work...
   } finally {
       await sandbox.process.deleteSession(session.sessionId);
   }
   ```

   ```ruby
   # Ruby - Clean up session
   session_id = 'long-running-cmd'
   begin
     sandbox.process.create_session(session_id)
     session = sandbox.process.get_session(session_id)
     # Do work...
   ensure
     sandbox.process.delete_session(session.session_id)
   end
   ```

See: [create_session (Python SDK)](https://www.daytona.io/docs/python-sdk/sync/process.md#processcreate_session), [delete_session (Python SDK)](https://www.daytona.io/docs/python-sdk/sync/process.md#processdelete_session), [createSession (TypeScript SDK)](https://www.daytona.io/docs/typescript-sdk/process.md#createsession), [deleteSession (TypeScript SDK)](https://www.daytona.io/docs/typescript-sdk/process.md#deletesession), [create_session (Ruby SDK)](https://www.daytona.io/docs/ruby-sdk/process.md#create_session), [delete_session (Ruby SDK)](https://www.daytona.io/docs/ruby-sdk/process.md#delete_session)

### Error Handling

The following best practices apply to error handling when executing processes:

- Handle process exceptions properly
- Log error details for debugging
- Use try-catch blocks for error handling

```python
try:
    response = sandbox.process.code_run("invalid python code")
except ProcessExecutionError as e:
    print(f"Execution failed: {e}")
    print(f"Exit code: {e.exit_code}")
    print(f"Error output: {e.stderr}")
```
```typescript
try {
    const response = await sandbox.process.codeRun("invalid typescript code");
} catch (e) {
    if (e instanceof ProcessExecutionError) {
        console.error("Execution failed:", e);
        console.error("Exit code:", e.exitCode);
        console.error("Error output:", e.stderr);
    }
}
```

```ruby
begin
  response = sandbox.process.code_run(code: 'invalid python code')
rescue Daytona::ProcessExecutionError => e
  puts "Execution failed: #{e}"
  puts "Exit code: #{e.exit_code}"
  puts "Error output: #{e.stderr}"
end
```

## Common Issues

To troubleshoot common issues related to process and code execution, refer to the following table:

| Issue | Solutions |
|-------|-----------|
| `Process Execution Failed` | • Check command syntax<br/>• Verify required dependencies<br/>• Ensure sufficient permissions |
| `Process Timeout` | • Adjust timeout settings<br/>• Optimize long-running operations<br/>• Consider using background processes |
| `Resource Limits` | • Monitor process memory usage<br/>• Handle process cleanup properly<br/>• Use appropriate resource constraints |