This topic describes how to use Code Interpreter in ApsaraDB RDS for PostgreSQL Supabase sandboxes to execute Python code in a secure isolated cloud environment with the e2b-code-interpreter SDK. Five typical scenarios are included.
Prerequisites
Make sure that you have created an RDS Supabase instance and the instance is in the Running state.
Make sure that the instance resides in one of the following 5 regions: China (Beijing), China (Shanghai), China (Hangzhou), China (Shenzhen), or China (Chengdu).
Make sure that the
AliyunServiceRoleForRDSAISupabaseservice-linked role is authorized.Make sure that the sandbox feature is enabled on the Sandboxes and edge functions page in the RDS console. For more information, see Use sandboxes and edge functions.
Limits
The default lifecycle of a single sandbox is controlled by the
timeoutparameter (up to 600 seconds in the samples). The sandbox is destroyed automatically after timeout. Split long-running tasks or extend the parameter value as needed.Scenario 5 (AI-powered data analysis agent) requires you to bring your own large language model service through the
LLM_API_KEYandLLM_BASE_URLenvironment variables. RDS Supabase sandboxes do not provide LLM capabilities.
Configure Code Interpreter
Complete the following 6 configuration items in order to prepare the Code Interpreter runtime environment.
Step 1: Create a code-interpreter sandbox template
Log on to the ApsaraDB RDS console and go to the details page of the target RDS Supabase instance.
In the left-side navigation pane, click Components > Sandboxes and edge functions.
Confirm that the Enable sandboxes and edge functions toggle at the top of the page is on.
In the Sandbox templates section on the right, locate the code-interpreter row and copy the value in the Template ID column. Replace the
<template-id>placeholder in all subsequent code samples (Sandbox.create(template="<template-id>")) with this value.
The preset sandbox templates include claude-code, code-interpreter, deno, desktop, and steel-browser, each for a different AI scenario. This topic focuses on code-interpreter; for other templates, see the corresponding scenario topics.
Step 2: Bind a domain name
Code Interpreter accesses the sandbox through an instance-specific domain <instance-id>.sb.rds.com. Add the following mapping to your local /etc/hosts:
<instance-ip> <instance-id>.sb.rds.comYou can find the instance IP address on the Basic information page of the RDS Supabase instance.
Write directly to /etc/hosts in development and testing environments. In production environments, manage domain names uniformly through DNS resolution.
Step 3: Download the e2b SDK patch code
Download the patch code from the GitHub repository aliyun-rds-pg/e2b-sdk-patch. This patch adapts to the RDS Supabase routing.
Step 4: (Optional) Configure SSL for HTTPS access
To access the sandbox through HTTPS, first configure an SSL certificate for the Supabase instance. For more information, see Configure SSL and enable HTTPS access for RDS Supabase.
After the SSL certificate is configured, set the following environment variables to point to the trusted root certificate file:
# rootCA.pem is the CA certificate used to generate the SSL certificate of the Supabase instance.
export SSL_CERT_FILE="/xxx/rootCA.pem"
export REQUESTS_CA_BUNDLE="/xxx/rootCA.pem"Step 5: Configure environment variables
Configure the following environment variables to let the SDK connect to the sandbox and the LLM service:
export E2B_DOMAIN=<instance-id>.sb.rds.com
export E2B_API_KEY=<your-service-key>
export LLM_API_KEY=<your-llm-api-key>
export LLM_BASE_URL=<your-llm-base-url>Environment variable | Description |
| The sandbox access domain, that is, the domain bound in Step 2. |
| The ServiceKey for sandbox authentication. On the instance details page, click Get API Key in the upper-right corner and copy the value of the ServiceKey field. |
| The API key of the LLM service. Required only for Scenario 5 (AI agent); can be left empty for other scenarios. |
| The Base URL of the LLM service. Required only for Scenario 5; can be left empty for other scenarios. |
Step 6: Install the e2b-code-interpreter SDK
pip install e2b-code-interpreter openaiCode Interpreter examples
The core workflow of Code Interpreter proceeds sequentially: create the sandbox, execute code or file operations, retrieve results, and destroy the sandbox. Compared with a local Python REPL, sandboxes provide a secure isolated cloud execution environment with support for stateful multi-turn execution, concurrent context isolation, and binary result retrieval. Each of the following 5 scenarios provides a complete runnable Python script. Copy the script, save it as a .py file as described in Run the example code, and execute it.
Scenario 1: Stateful multi-turn code execution
Calling run_code multiple times within the same sandbox retains variables and imported modules across turns, suitable for building analysis workflows step by step. Use a with statement to destroy the sandbox automatically on exit.
from e2b_code_interpreter import Sandbox
from patch_e2b import patch_e2b
patch_e2b(True)
with Sandbox.create(template="<template-id>") as sbx:
sbx.run_code("x = 10")
execution = sbx.run_code("x += 5; print(f'x = {x}')")
print(execution.logs.stdout) # x = 15
sbx.run_code("import math")
execution = sbx.run_code("print(f'pi = {math.pi}')")
print(execution.logs.stdout) # pi = 3.141592653589793Scenario 2: File read and write operations
Interact with the sandbox file system through sbx.files.write and sbx.files.read, and let libraries such as pandas in run_code consume the local files directly, unifying file operations and code execution.
from e2b_code_interpreter import Sandbox
from patch_e2b import patch_e2b
patch_e2b(True)
with Sandbox.create(template="<template-id>") as sbx:
sbx.files.write("/home/user/data.csv", "name,age,city\nAlice,30,Beijing\nBob,25,Shanghai")
content = sbx.files.read("/home/user/data.csv")
execution = sbx.run_code("""
import pandas as pd
df = pd.read_csv('/home/user/data.csv')
print(df.describe())
""")
print(execution.logs.stdout)Scenario 3: Code contexts isolation
Code contexts let you create multiple independent code contexts within the same sandbox. Each context maintains its own variables and state, suitable for scenarios that require state isolation across tasks, for example running data analysis and report generation in parallel without interference.
Example 1: Create, use, and verify isolation
from e2b_code_interpreter import Sandbox
from patch_e2b import patch_e2b
patch_e2b(True)
sandbox = Sandbox.create(template="<template-id>")
try:
# Create two independent code contexts
data_ctx = sandbox.create_code_context()
report_ctx = sandbox.create_code_context()
# Prepare data in data_ctx
sandbox.run_code("""
import pandas as pd
import numpy as np
np.random.seed(42)
dates = pd.date_range('2025-01-01', periods=30)
data = pd.DataFrame({'date': dates, 'revenue': np.random.randint(1000, 5000, 30)})
print(data.head())
""", context=data_ctx)
# Generate report in report_ctx (independent environment, not affected by data_ctx)
sandbox.run_code("""
report_lines = [
'=== Data analysis report ===',
f'Generated: 2025-07-02',
'State: The data context and this context are isolated from each other',
]
for line in report_lines:
print(line)
""", context=report_ctx)
# Verify isolation: the data variable in data_ctx does not exist in report_ctx
result = sandbox.run_code("print('data' in dir())", context=report_ctx)
print(f'Does data variable exist in report_ctx: {result.logs.stdout[0]}') # False
finally:
sandbox.kill()Example 2: List, restart, and delete contexts
The SDK provides a full set of APIs for managing contexts, including listing all active contexts, restarting a context (clearing its state), and deleting a context. These operations help you flexibly manage multiple execution environments in complex scenarios.
from e2b_code_interpreter import Sandbox
from patch_e2b import patch_e2b
patch_e2b(True)
sandbox = Sandbox.create(template="<template-id>")
try:
data_ctx = sandbox.create_code_context()
report_ctx = sandbox.create_code_context()
# List all active contexts
contexts = sandbox.list_code_contexts()
print(f'Number of active contexts: {len(contexts)}')
# Restart a context (clear its state and start fresh)
data_ctx = sandbox.restart_code_context(data_ctx)
print(f'Restarted context: {data_ctx.id}')
# Delete a context (through the object)
sandbox.remove_code_context(report_ctx)
print('Removed report_ctx')
# You can also delete through context_id
sandbox.remove_code_context(data_ctx.id)
print('Removed data_ctx')
finally:
sandbox.kill()The context management APIs (list_code_contexts, restart_code_context, remove_code_context) accept either a context object or a context_id string.
Scenario 4: Data analysis and visualization
Use matplotlib inside the sandbox to generate charts, then retrieve the PNG bytes to the local disk through sbx.files.read(..., format="bytes").
from e2b_code_interpreter import Sandbox
from patch_e2b import patch_e2b
patch_e2b(True)
sandbox = Sandbox.create(template="<template-id>", timeout=300)
try:
execution = sandbox.run_code("""
import numpy as np
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
np.random.seed(42)
days = np.arange(1, 31)
prices = 120 + np.cumsum(np.random.randn(30) * 2)
fig, ax = plt.subplots(figsize=(12, 6))
ax.plot(days, prices, 'b-', linewidth=2, marker='o')
ax.set_title('Simulated 30-Day Price Trend')
plt.tight_layout()
plt.savefig('/home/user/chart.png', dpi=150)
print(f'Price range: {prices.min():.2f} - {prices.max():.2f}')
""")
print(execution.logs.stdout)
chart_bytes = sandbox.files.read("/home/user/chart.png", format="bytes")
with open("chart.png", "wb") as f:
f.write(chart_bytes)
print("Chart saved")
finally:
sandbox.kill()The sandbox is a headless environment. You must explicitly set the matplotlib backend to Agg with matplotlib.use('Agg') in the code. Otherwise, calling plt.savefig may fail due to the missing display backend.
Scenario 5: AI-powered data analysis agent
Combine the tool calling capability of an LLM with Code Interpreter to build an intelligent data analysis assistant. The workflow proceeds sequentially: upload the data file, have the LLM generate analysis code, execute the code in the sandbox to produce a chart, and save the result to the local disk. The following example uses the TMDB movie dataset (approximately 10,000 records), letting the LLM generate visualization code and executing it in the sandbox.
Install dependencies
pip install e2b-code-interpreter openai python-dotenvComplete code
import sys
import os
import json
import base64
from dotenv import load_dotenv
load_dotenv()
from e2b_code_interpreter import Sandbox
from patch_e2b import patch_e2b
from openai import OpenAI
patch_e2b(True)
client = OpenAI(
api_key=os.getenv("LLM_API_KEY"),
base_url=os.getenv("LLM_BASE_URL"),
)
# Create the sandbox and upload the dataset
sbx = Sandbox.create(template="<template-id>", timeout=300)
with open("dataset.csv", "rb") as f:
dataset_path = sbx.files.write("/home/user/dataset.csv", f)
def run_ai_generated_code(ai_code: str):
"""Execute the code generated by the AI and save the resulting chart."""
print("Executing code in the sandbox...")
execution = sbx.run_code(ai_code)
print("Code execution completed.")
if execution.error:
print(f"Execution error: {execution.error.value}")
print(execution.error.traceback)
return
# Extract the chart (PNG) and save it
for idx, result in enumerate(execution.results):
if result.png:
with open(f"chart-{idx}.png", "wb") as f:
f.write(base64.b64decode(result.png))
print(f"Chart saved to chart-{idx}.png")
if execution.logs.stdout:
print(f"Output: {execution.logs.stdout}")
# Build the prompt: describe the data and the analysis requirement
prompt = f"""
I have a CSV file about movies with approximately 10,000 records, saved in the sandbox at {dataset_path.path}.
The columns and their meanings are:
- id: number, the unique identifier of the movie
- original_language: string, the original language, such as "eng", "es", "ko"
- original_title: string, the original title of the movie
- overview: string, a short overview of the movie
- popularity: float, popularity score in an approximate range of 0 to 9137.939, not normalized and contains outliers
- release_date: date, in the format yyyy-mm-dd
- title: string, the English title of the movie
- vote_average: float, the average audience rating, ranging from 0 to 10
- vote_count: integer, the number of votes
Please write Python code to plot a line chart that shows the trend of vote_average (the average audience rating) over the years.
There is no need to print or explore the data; visualize directly.
Important: The last line of the code must be the following statement, which displays the chart:
display(plt.gcf())
"""
# Use tool calling to let the LLM generate the code
print("Waiting for the LLM response...")
msg = client.chat.completions.create(
model="qwen3.7-plus",
messages=[{"role": "user", "content": prompt}],
tools=[{
"type": "function",
"function": {
"name": "run_python_code",
"description": "Run Python code in the sandbox",
"parameters": {
"type": "object",
"properties": {
"code": {"type": "string", "description": "The Python code to execute"},
},
"required": ["code"],
},
},
}],
)
# Parse the response and execute the generated code
for tool_call in msg.choices[0].message.tool_calls:
if tool_call.function.name == "run_python_code":
code = json.loads(tool_call.function.arguments)["code"]
print("Code generated by the AI:")
print(code)
run_ai_generated_code(code)
sbx.kill()
print("Sandbox resources cleaned up")Workflow description
Upload data: Upload the local CSV file to
/home/user/dataset.csvin the sandbox.Prompt construction: Describe the data column definitions and analysis requirements to the LLM, and require the code to end with
display(plt.gcf()).Tool calling: Let the LLM return the code as a tool argument through the OpenAI function calling protocol.
Sandbox execution: Call
sbx.run_code()to execute the code, and extract the base64-encoded chart from thepngfield inexecution.results.Save the result: Decode the PNG through
base64.b64decodeand save it to the local disk.
Run the example code
Save and run the example code of any scenario as follows.
Step 1: Create the script file
Save the example code as a .py file. The file must be in the same directory as the patch_e2b source code downloaded in Step 3 of "Configure Code Interpreter". Otherwise, the error ModuleNotFoundError: No module named 'patch_e2b' occurs. Example directory structure:
e2b-sdk-patch/
├── patch_e2b/ # patch source code downloaded in Step 3 of "Configure Code Interpreter"
├── main.py # your example script
├── .env # only for Scenario 5, stores LLM credentials
└── dataset.csv # only for Scenario 5, the dataset to analyzeTo place the script in a different directory, add the patch_e2b source path to PYTHONPATH:
export PYTHONPATH="/path/to/e2b-sdk-patch:$PYTHONPATH"/path/to/e2b-sdk-patch is a placeholder. Replace it with the actual absolute path of the local patch_e2b source (for example, /Users/yourname/code/e2b-sdk-patch). :$PYTHONPATH preserves the existing paths so they are not overwritten. After the configuration, run the script in the same terminal window for the setting to take effect.
Step 2: Replace the placeholder in the code
Replace the <template-id> in the example code with the template ID recorded in Step 1 of "Configure Code Interpreter".
patch_e2b(True) must be called before any Sandbox-related invocation. Otherwise, the SDK falls back to the default upstream routing instead of the RDS Supabase custom routing.
Step 3: Confirm that the environment variables are effective
Before starting the script, make sure the 4 environment variables defined in Step 5 of "Configure Code Interpreter" are loaded:
E2B_DOMAIN=<instance-id>.sb.rds.com
E2B_API_KEY=<your-service-key>
LLM_API_KEY=<your-llm-api-key>
LLM_BASE_URL=<your-llm-base-url>Step 4: Run the script
Execute in the working directory:
python3 demo.pyOn the first run, the console prints the sandbox ID (sandbox_id), indicating that the sandbox has been created successfully. After execution completes, confirm that the sandbox is destroyed through sbx.kill() or the with statement to avoid quota residue.
Common startup issues
Q1: What should I do if SSL: CERTIFICATE_VERIFY_FAILED occurs during execution?
A: The SSL certificate is not configured. Return to Step 4 of "Configure Code Interpreter" and set SSL_CERT_FILE and REQUESTS_CA_BUNDLE to point to a trusted root certificate file.
Q2: What should I do if Sandbox.create reports "template not found"?
A: Verify that <template-id> is the full Template ID from the code-interpreter row in the Sandbox templates table on the console (not the configuration item name code-interpreter), and that the instance has Sandboxes and edge functions enabled.
Q3: What should I do if domain resolution fails with Name or service not known?
A: Verify that <instance-ip> <instance-id>.sb.rds.com has been added to your local /etc/hosts, and that the E2B_DOMAIN environment variable matches exactly.