# Code Execution

Daytona runs Python, TypeScript, and JavaScript code in sandboxes through language kernels, so untrusted or generated code executes in isolation from your application.

Every run is a `code` process that executes in a session with a language kernel. The kernel keeps state between runs in the same session, so variables, imports, and functions defined in one run are available in the next. Runs use a shared kernel per language by default; isolated runs and interpreter contexts give code its own kernel. To run shell commands and manage long-running processes, see [process execution](https://www.daytona.io/docs/en/v2/process-execution.md). To follow a run's output live, see [log streaming](https://www.daytona.io/docs/en/v2/log-streaming.md).

## Use cases

Code execution is used when an application runs Python, TypeScript, or JavaScript that it did not write or does not trust.

- **AI-generated code**: an agent writes code, runs it in the sandbox, and reads the output and errors to correct its next attempt. The code runs isolated from your application.
- **Data analysis**: the kernel keeps data, imports, and functions in memory between runs, so each step builds on the previous one, as in a notebook.
- **Charts and tables**: runs that plot or display data return charts and tables as artifacts with the result. Each artifact is keyed by MIME type, so an application renders it in the right format.
- **Code interpreters for users**: each user or conversation gets its own interpreter context, so state from one does not reach another. A context has its own kernel, working directory, and environment.
- **Workers that share a context**: contexts are addressed by ID. Any worker or process with the sandbox ID and the context ID runs code in the same context.
- **Live output from long runs**: the output of a run streams through [log streaming](https://www.daytona.io/docs/en/v2/log-streaming.md) while the code still runs. Exceptions arrive with their name, value, and traceback.
- **One-off runs**: an isolated kernel runs code with no state from earlier runs. The session is deleted after the run, so nothing the code defines reaches other runs.

## Run code

Run code in a sandbox. Runs without a context share one kernel per language, so state from one run is available to later runs in that language. The default language is Python.

The result contains the standard output and standard error, rich outputs, the exception if the code raised one, and the exit status of the process.


```python
from daytona import Daytona

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

response = sandbox.run_code('''
def greet(name):
    return f"Hello, {name}!"

print(greet("Daytona"))
''')
print(response.logs.stdout)
```

| **Parameter** | **Type**                 | **Description**                                                                                                  |
| ------------- | ------------------------ | ---------------------------------------------------------------------------------------------------------------- |
| **`code`** | **`str`** | Sets the code to run. This parameter is required. |
| **`language`** | **`str`** | Sets the language: **`python`**, **`typescript`**, or **`javascript`**. The default is **`python`**. |
| **`context`** | **`InterpreterContext`** | Runs the code in an [interpreter context](#interpreter-contexts) instead of the shared kernel. |
| **`isolated`** | **`bool`** | Runs the code in a [temporary kernel](#run-code-in-an-isolated-kernel). The default is **`False`**. |
| **`cwd`** | **`str`** | Sets the working directory for the run. |
| **`env`** | **`Mapping[str, str]`** | Sets environment variables for the shared kernel. The variables apply when the kernel is first created. |
| **`timeout`** | **`float`** | Sets how many seconds the client waits. **`0`** means no limit. On timeout, the kernel is interrupted and the interrupted result is returned. |

The response has the following fields:

| **Field** | **Description** |
| --------- | --------------- |
| **`logs`** | Holds the standard output and standard error. |
| **`results`** | Holds the rich outputs. |
| **`error`** | Holds the exception, if the code raised one. |
| **`process`** | Holds the exit status of the process. |

- **`run_code`** is a shortcut for **`sandbox.interpreter.run`** and accepts the same parameters.


```typescript
import { Daytona } from '@daytona/sdk'

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

const response = await sandbox.runCode(`
def greet(name):
    return f"Hello, {name}!"

print(greet("Daytona"))
`)
console.log(response.logs.stdout)
```

| **Parameter** | **Type**                 | **Description**                                                                                                       |
| ------------- | ------------------------ | --------------------------------------------------------------------------------------------------------------------- |
| **`code`** | **`string`** | Sets the code to run. This parameter is required. |
| **`language`** | **`string`** | Sets the language: **`'python'`**, **`'typescript'`**, or **`'javascript'`**. The default is **`'python'`**. |
| **`context`** | **`InterpreterContextReference \| InterpreterContextJSON`** | Runs the code in an [interpreter context](#interpreter-contexts) instead of the shared kernel. |
| **`isolated`** | **`boolean`** | Runs the code in a [temporary kernel](#run-code-in-an-isolated-kernel). |
| **`cwd`** | **`string`** | Sets the working directory for the run. |
| **`env`** | **`Record<string, string>`** | Sets environment variables for the shared kernel. The variables apply when the kernel is first created. |
| **`timeout`** | **`number`** | Sets how many milliseconds the client waits. **`0`** means no limit. On timeout, the kernel is interrupted and the interrupted result is returned. |

The response has the following fields:

| **Field** | **Description** |
| --------- | --------------- |
| **`logs`** | Holds the standard output and standard error. |
| **`results`** | Holds the rich outputs. |
| **`error`** | Holds the exception, if the code raised one. |
| **`process`** | Holds the exit status of the process. |

- **`runCode`** is a shortcut for **`sandbox.interpreter.run`** and accepts the same options.


```bash
# Without sessionId the code runs on the shared per-language session "code-python"
curl 'https://toolbox.daytona.com/toolbox/{sandboxId}/processes?waitMs=5000&logs=text' \
  --request POST \
  --header 'Content-Type: application/json' \
  --header 'Authorization: Bearer YOUR_API_KEY' \
  --data '{
  "kind": "code",
  "language": "python",
  "code": "def greet(name):\n    return f\"Hello, {name}!\"\n\nprint(greet(\"Daytona\"))"
}'
```

| **Field**   | **Type** | **Description**                                                                                |
| ----------- | -------- | ---------------------------------------------------------------------------------------------- |
| **`kind`** | **`string`** | Sets the process kind. Use **`code`** for a code run. |
| **`language`** | **`string`** | Sets the language: **`python`**, **`typescript`**, or **`javascript`**. |
| **`code`** | **`string`** | Sets the code to run. |
| **`sessionId`** | **`string`** | Runs the code in an [interpreter context](#interpreter-contexts). Without **`sessionId`**, the code runs on the shared per-language session. |

The response has the following fields:

| **Field** | **Description** |
| --------- | --------------- |
| **`state`** | The first run in a language installs and starts the kernel. If that takes longer than **`waitMs`**, the state is **`provisioning`** or **`running`**. Wait with **`GET /processes/{processId}/wait`**, then read the logs. |


### Artifacts

Rich outputs such as charts and tables are returned with the result, keyed by MIME type.


```python
from daytona import Daytona

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

code = '''
import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(0, 10, 30)
plt.plot(x, np.sin(x))
plt.title("Sine wave")
plt.show()
'''

response = sandbox.run_code(code)
for result in response.results:
    print(list(result.data))  # MIME types, for example ['image/png', 'text/plain']
```

The response has the following fields:

| **Field** | **Description** |
| --------- | --------------- |
| **`results`** | Holds the rich outputs. |
| **`text`**, **`html`**, **`png`**, **`svg`**, **`json`** | Each of these fields of a result mirrors the matching MIME type in **`data`**. |
| **`is_main_result`** | Is **`True`** for the value of the last expression and **`False`** for displayed outputs. |


```typescript
import { Daytona } from '@daytona/sdk'

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

const response = await sandbox.runCode(`
import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(0, 10, 30)
plt.plot(x, np.sin(x))
plt.title("Sine wave")
plt.show()
`)

for (const result of response.results) {
    console.log(Object.keys(result.data)) // MIME types, for example ['image/png', 'text/plain']
}
```

The response has the following fields:

| **Field** | **Description** |
| --------- | --------------- |
| **`results`** | Holds the rich outputs. |
| **`text`**, **`html`**, **`png`**, **`svg`**, **`json`** | Each of these fields of a result mirrors the matching MIME type in **`data`**. |
| **`isMainResult`** | Is **`true`** for the value of the last expression and **`false`** for displayed outputs. |


```bash
# Rich outputs arrive as log frames on the "display" and "execute_result" channels.
# Each frame's data is a JSON MIME bundle, for example {"image/png": "...", "text/plain": "..."}.
curl 'https://toolbox.daytona.com/toolbox/{sandboxId}/processes?waitMs=60000&logs=text' \
  --request POST \
  --header 'Content-Type: application/json' \
  --header 'Authorization: Bearer YOUR_API_KEY' \
  --data '{
  "kind": "code",
  "language": "python",
  "code": "import matplotlib.pyplot as plt\nimport numpy as np\n\nx = np.linspace(0, 10, 30)\nplt.plot(x, np.sin(x))\nplt.title(\"Sine wave\")\nplt.show()"
}'
```


## Run code in an isolated kernel

Run code in a temporary kernel that starts with no state. Daytona creates a session with a new kernel, runs the code, and deletes the session after the run. Nothing the code defines is visible to other runs, and the code does not see state from the shared kernel or from interpreter contexts.


```python
from daytona import Daytona

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

sandbox.run_code("value = 42")

# The isolated kernel does not see variables from the shared kernel
response = sandbox.run_code("print(value)", isolated=True)
if response.error:
    print(response.error.name)  # NameError
```

| **Parameter** | **Type**          | **Description**                                         |
| ------------- | ----------------- | ------------------------------------------------------- |
| **`isolated`** | **`bool`** | Runs the code in a temporary kernel when set to **`True`**. The default is **`False`**. |
| **`cwd`** | **`str`** | Sets the working directory of the temporary kernel. |
| **`env`** | **`Mapping[str, str]`** | Sets environment variables of the temporary kernel. |


```typescript
import { Daytona } from '@daytona/sdk'

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

await sandbox.runCode('value = 42')

// The isolated kernel does not see variables from the shared kernel
const response = await sandbox.runCode('print(value)', { isolated: true })
console.log(response.error?.name) // NameError
```

| **Parameter** | **Type**                 | **Description**                                              |
| ------------- | ------------------------ | ------------------------------------------------------------ |
| **`isolated`** | **`boolean`** | Runs the code in a temporary kernel when set to **`true`**. **`isolated: true`** cannot be combined with **`context`** or **`sessionId`**. The default is **`false`**. |
| **`cwd`** | **`string`** | Sets the working directory of the temporary kernel. |
| **`env`** | **`Record<string, string>`** | Sets environment variables of the temporary kernel. |


```bash
# Create a session with a new kernel
curl 'https://toolbox.daytona.com/toolbox/{sandboxId}/sessions' \
  --request POST \
  --header 'Content-Type: application/json' \
  --header 'Authorization: Bearer YOUR_API_KEY' \
  --data '{"id": "isolated-run", "kernel": "python"}'

# Run the code in that session
curl 'https://toolbox.daytona.com/toolbox/{sandboxId}/processes?waitMs=60000&logs=text' \
  --request POST \
  --header 'Content-Type: application/json' \
  --header 'Authorization: Bearer YOUR_API_KEY' \
  --data '{"kind": "code", "language": "python", "sessionId": "isolated-run", "code": "print(value)"}'

# Delete the session and its kernel
curl 'https://toolbox.daytona.com/toolbox/{sandboxId}/sessions/isolated-run' \
  --request DELETE \
  --header 'Authorization: Bearer YOUR_API_KEY'
```

- Delete the session even when the run fails.
- The kernel keeps running until you delete the session.


## Interpreter contexts

An interpreter context is a session with its own language kernel, working directory, and environment. State persists across runs in a context and is not shared with the shared kernel or other contexts. A context lives until deleted, so its kernel uses memory while idle.

In the Toolbox API, a context is a [session](https://www.daytona.io/docs/en/v2/api.md) whose `kernel` is a language. Sessions with a `shell` kernel run shell commands; see [sessions](https://www.daytona.io/docs/en/v2/process-execution.md#sessions).

### Create a context

Create an interpreter context and run code in it. Run code with the context handle, or pass the handle to a run in the sandbox.


```python
from daytona import Daytona

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

ctx = sandbox.interpreter.create_context(language="python", env={"STAGE": "dev"})
try:
    ctx.run("value = 'stored in ctx'")
    result = sandbox.run_code("print(value)", context=ctx)
    print(result.logs.stdout)
finally:
    ctx.close()
```

| **Parameter** | **Type**            | **Description**                                                         |
| ------------- | ------------------- | ----------------------------------------------------------------------- |
| **`language`** | **`str`** | Sets the language: **`python`**, **`typescript`**, or **`javascript`**. This parameter is required. |
| **`context_id`** | **`str`** | Sets the context ID for reconnecting later. If omitted, an ID is generated. |
| **`cwd`** | **`str`** | Sets the working directory of the kernel. |
| **`env`** | **`Mapping[str, str]`** | Sets the kernel environment variables. Runs in a context do not accept **`env`**. |

- **`create_context()`** starts the kernel before it returns.
- The first context or run in a language also installs the kernel, so the call can take longer than a run.


```typescript
import { Daytona } from '@daytona/sdk'

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

const ctx = await sandbox.interpreter.createContext({ language: 'python', env: { STAGE: 'dev' } })
try {
    await ctx.run(`value = 'stored in ctx'`)
    const result = await sandbox.runCode(`print(value)`, { context: ctx })
    console.log(result.logs.stdout)
} finally {
    await ctx.close()
}
```

| **Parameter** | **Type**                 | **Description**                                                         |
| ------------- | ------------------------ | ----------------------------------------------------------------------- |
| **`language`** | **`string`** | Sets the language: **`'python'`**, **`'typescript'`**, or **`'javascript'`**. This parameter is required. |
| **`id`** | **`string`** | Sets the context ID for reconnecting later. If omitted, an ID is generated. |
| **`cwd`** | **`string`** | Sets the working directory of the kernel. |
| **`env`** | **`Record<string, string>`** | Sets the kernel environment variables. Runs in a context do not accept **`env`**. |

- **`createContext()`** starts the kernel before it resolves.
- The first context or run in a language also installs the kernel, so the call can take longer than a run.


```bash
# Create a context (session with a language kernel). Omit "id" to get a generated one.
curl 'https://toolbox.daytona.com/toolbox/{sandboxId}/sessions' \
  --request POST \
  --header 'Content-Type: application/json' \
  --header 'Authorization: Bearer YOUR_API_KEY' \
  --data '{"id": "my-context", "kernel": "python", "env": {"STAGE": "dev"}}'

# Run code in the context; state persists between runs
curl 'https://toolbox.daytona.com/toolbox/{sandboxId}/processes?waitMs=60000&logs=text' \
  --request POST \
  --header 'Content-Type: application/json' \
  --header 'Authorization: Bearer YOUR_API_KEY' \
  --data '{"kind": "code", "language": "python", "sessionId": "my-context", "code": "value = \"stored in ctx\""}'

curl 'https://toolbox.daytona.com/toolbox/{sandboxId}/processes?waitMs=60000&logs=text' \
  --request POST \
  --header 'Content-Type: application/json' \
  --header 'Authorization: Bearer YOUR_API_KEY' \
  --data '{"kind": "code", "language": "python", "sessionId": "my-context", "code": "print(value)"}'
```

| **Field** | **Type** | **Description**                                                                         |
| --------- | -------- | --------------------------------------------------------------------------------------- |
| **`id`** | **`string`** | Sets the context ID for reconnecting later. If omitted, an ID is generated. |
| **`kernel`** | **`string`** | Sets the context language: **`python`**, **`typescript`**, or **`javascript`**. |
| **`env`** | **`object`** | Sets the kernel environment variables. Runs in a context do not accept **`env`**. |

- The request starts the kernel before it returns.
- On first use, the request also installs the kernel.


### List contexts

List a sandbox's interpreter contexts. The API also lists shell sessions; the SDKs do not.


```python
from daytona import Daytona

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

for ctx in sandbox.interpreter.list_contexts():
    print(f"Context: {ctx.context_id}, Language: {ctx.language}")
```


```typescript
import { Daytona } from '@daytona/sdk'

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

for (const ctx of await sandbox.interpreter.listContexts()) {
  console.log(`Context: ${ctx.id}, Language: ${ctx.language}`)
}
```


```bash
curl 'https://toolbox.daytona.com/toolbox/{sandboxId}/sessions' \
  --header 'Authorization: Bearer YOUR_API_KEY'
```


### Reconnect to a context

Reconnect to an existing context from another worker or process. Contexts are addressed by ID, so any client with the sandbox ID and the context ID can run code in the context.


```python
from daytona import Daytona

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

# Worker A: create a context with a known ID
ctx = sandbox.interpreter.create_context(language="python", context_id="my-context")
ctx.run("x = 42")

# Worker B: reconnect to the context by ID
context = sandbox.interpreter.connect_context("my-context", language="python")
response = context.run("print(x)")
```

| **Parameter** | **Type** | **Description**                                                                                        |
| ------------- | -------- | ------------------------------------------------------------------------------------------------------ |
| **`language`** | **`str`** | Sets the context language. This parameter is required when you pass an ID. Without **`language`**, **`connect_context()`** raises **`DaytonaError`** with code **`BAD_REQUEST`**. |

- **`connect_context()`** returns a handle for the context ID and language without a request or existence check.
- A run in a deleted context fails.


```typescript
import { Daytona } from '@daytona/sdk'

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

// Worker A: create a context with a known ID
const ctx = await sandbox.interpreter.createContext({ id: 'my-context', language: 'python' })
await ctx.run('x = 42')

// Worker B: reconnect to the context by ID
const context = sandbox.interpreter.connectContext('my-context', 'python')
const response = await context.run('print(x)')
```

- **`connectContext()`** returns a handle for the context ID and language without a request or existence check.
- A run in a deleted context fails.


```bash
# Run code in the context from any client
curl 'https://toolbox.daytona.com/toolbox/{sandboxId}/processes?waitMs=5000&logs=text' \
  --request POST \
  --header 'Content-Type: application/json' \
  --header 'Authorization: Bearer YOUR_API_KEY' \
  --data '{"kind": "code", "language": "python", "code": "print(x)", "sessionId": "my-context"}'
```


### Delete a context

Delete an interpreter context. Deleting a context shuts its kernel down and frees its memory.


```python
from daytona import Daytona

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

ctx = sandbox.interpreter.create_context(language="python")
try:
    ctx.run("data = list(range(10_000_000))")
finally:
    sandbox.interpreter.delete_context(ctx)
```

- **`delete_context()`** takes a handle or ID.
- **`ctx.close()`** deletes the context of a handle.


```typescript
import { Daytona } from '@daytona/sdk'

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

const ctx = await sandbox.interpreter.createContext({ language: 'python' })
try {
    await ctx.run('data = list(range(10_000_000))')
} finally {
    await sandbox.interpreter.deleteContext(ctx)
}
```

- **`deleteContext()`** takes a handle or ID.
- **`ctx.close()`** deletes the context of a handle.


```bash
curl 'https://toolbox.daytona.com/toolbox/{sandboxId}/sessions/my-context' \
  --request DELETE \
  --header 'Authorization: Bearer YOUR_API_KEY'
```

- A run still in progress in the context ends with **`reason`** **`lost`**.
- The record of that run is removed.