@computesdk/e2b 1.1.0 → 1.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +216 -354
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,15 +1,6 @@
|
|
|
1
1
|
# @computesdk/e2b
|
|
2
2
|
|
|
3
|
-
E2B provider for ComputeSDK - Execute
|
|
4
|
-
|
|
5
|
-
## Features
|
|
6
|
-
|
|
7
|
-
- 🐍 **Python Code Execution** - Run Python scripts with data science libraries
|
|
8
|
-
- 📁 **Full Filesystem Access** - Read, write, create directories, and manage files
|
|
9
|
-
- 🖥️ **Interactive Terminals** - PTY terminal sessions with real-time I/O
|
|
10
|
-
- ⚡ **Command Execution** - Run shell commands directly
|
|
11
|
-
- 🔒 **Secure Isolation** - Each sandbox runs in its own isolated environment
|
|
12
|
-
- 📊 **Data Science Ready** - Pre-installed pandas, numpy, matplotlib, scikit-learn
|
|
3
|
+
E2B provider for ComputeSDK - Execute code in secure, isolated E2B sandboxes with full filesystem and terminal support.
|
|
13
4
|
|
|
14
5
|
## Installation
|
|
15
6
|
|
|
@@ -26,17 +17,24 @@ npm install @computesdk/e2b
|
|
|
26
17
|
export E2B_API_KEY=e2b_your_api_key_here
|
|
27
18
|
```
|
|
28
19
|
|
|
29
|
-
##
|
|
20
|
+
## Usage
|
|
30
21
|
|
|
31
|
-
###
|
|
22
|
+
### With ComputeSDK
|
|
32
23
|
|
|
33
24
|
```typescript
|
|
25
|
+
import { compute } from 'computesdk';
|
|
34
26
|
import { e2b } from '@computesdk/e2b';
|
|
35
27
|
|
|
36
|
-
|
|
28
|
+
// Set as default provider
|
|
29
|
+
compute.setConfig({
|
|
30
|
+
provider: e2b({ apiKey: process.env.E2B_API_KEY })
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
// Create sandbox
|
|
34
|
+
const sandbox = await compute.sandbox.create({});
|
|
37
35
|
|
|
38
36
|
// Execute Python code
|
|
39
|
-
const result = await sandbox.
|
|
37
|
+
const result = await sandbox.runCode(`
|
|
40
38
|
import pandas as pd
|
|
41
39
|
import numpy as np
|
|
42
40
|
|
|
@@ -54,73 +52,213 @@ console.log(result.stdout);
|
|
|
54
52
|
// 2 3 6
|
|
55
53
|
// Sum: 21
|
|
56
54
|
|
|
57
|
-
|
|
55
|
+
// Clean up
|
|
56
|
+
await compute.sandbox.destroy(sandbox.sandboxId);
|
|
58
57
|
```
|
|
59
58
|
|
|
60
|
-
###
|
|
59
|
+
### Direct Usage
|
|
61
60
|
|
|
62
61
|
```typescript
|
|
63
|
-
import {
|
|
62
|
+
import { e2b } from '@computesdk/e2b';
|
|
64
63
|
|
|
65
|
-
//
|
|
66
|
-
const
|
|
64
|
+
// Create provider
|
|
65
|
+
const provider = e2b({
|
|
66
|
+
apiKey: 'e2b_your_api_key',
|
|
67
|
+
timeout: 600000 // 10 minutes
|
|
68
|
+
});
|
|
67
69
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
+
// Use with compute singleton
|
|
71
|
+
const sandbox = await compute.sandbox.create({ provider });
|
|
70
72
|
```
|
|
71
73
|
|
|
72
|
-
##
|
|
74
|
+
## Configuration
|
|
73
75
|
|
|
74
|
-
|
|
76
|
+
### Environment Variables
|
|
75
77
|
|
|
76
|
-
|
|
78
|
+
```bash
|
|
79
|
+
export E2B_API_KEY=e2b_your_api_key_here
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### Configuration Options
|
|
77
83
|
|
|
78
84
|
```typescript
|
|
79
|
-
|
|
85
|
+
interface E2BConfig {
|
|
86
|
+
/** E2B API key - if not provided, will use E2B_API_KEY env var */
|
|
87
|
+
apiKey?: string;
|
|
88
|
+
/** Default runtime environment */
|
|
89
|
+
runtime?: 'python' | 'node';
|
|
90
|
+
/** Execution timeout in milliseconds */
|
|
91
|
+
timeout?: number;
|
|
92
|
+
}
|
|
93
|
+
```
|
|
80
94
|
|
|
81
|
-
|
|
95
|
+
## Features
|
|
82
96
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
97
|
+
- ✅ **Code Execution** - Python and Node.js runtime support
|
|
98
|
+
- ✅ **Command Execution** - Run shell commands in sandbox
|
|
99
|
+
- ✅ **Filesystem Operations** - Full file system access via E2B API
|
|
100
|
+
- ✅ **Terminal Support** - Interactive PTY terminals
|
|
101
|
+
- ✅ **Auto Runtime Detection** - Automatically detects Python vs Node.js
|
|
102
|
+
- ✅ **Data Science Ready** - Pre-installed pandas, numpy, matplotlib, etc.
|
|
88
103
|
|
|
89
|
-
|
|
90
|
-
const content = await sandbox.filesystem.readFile('/tmp/data.json');
|
|
91
|
-
console.log(JSON.parse(content)); // { name: 'ComputeSDK', version: '1.0.0' }
|
|
104
|
+
## API Reference
|
|
92
105
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
106
|
+
### Code Execution
|
|
107
|
+
|
|
108
|
+
```typescript
|
|
109
|
+
// Execute Python code
|
|
110
|
+
const result = await sandbox.runCode(`
|
|
111
|
+
import json
|
|
112
|
+
data = {"message": "Hello from Python"}
|
|
113
|
+
print(json.dumps(data))
|
|
114
|
+
`, 'python');
|
|
115
|
+
|
|
116
|
+
// Execute Node.js code
|
|
117
|
+
const result = await sandbox.runCode(`
|
|
118
|
+
const data = { message: "Hello from Node.js" };
|
|
119
|
+
console.log(JSON.stringify(data));
|
|
120
|
+
`, 'node');
|
|
121
|
+
|
|
122
|
+
// Auto-detection (based on code patterns)
|
|
123
|
+
const result = await sandbox.runCode('print("Auto-detected as Python")');
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
### Command Execution
|
|
127
|
+
|
|
128
|
+
```typescript
|
|
129
|
+
// List files
|
|
130
|
+
const result = await sandbox.runCommand('ls', ['-la']);
|
|
131
|
+
|
|
132
|
+
// Install packages
|
|
133
|
+
const result = await sandbox.runCommand('pip', ['install', 'requests']);
|
|
96
134
|
|
|
97
|
-
//
|
|
98
|
-
await sandbox.
|
|
135
|
+
// Run scripts
|
|
136
|
+
const result = await sandbox.runCommand('python', ['script.py']);
|
|
99
137
|
```
|
|
100
138
|
|
|
101
|
-
###
|
|
139
|
+
### Filesystem Operations
|
|
102
140
|
|
|
103
141
|
```typescript
|
|
104
|
-
//
|
|
105
|
-
await sandbox.filesystem.
|
|
106
|
-
|
|
142
|
+
// Write file
|
|
143
|
+
await sandbox.filesystem.writeFile('/tmp/hello.py', 'print("Hello World")');
|
|
144
|
+
|
|
145
|
+
// Read file
|
|
146
|
+
const content = await sandbox.filesystem.readFile('/tmp/hello.py');
|
|
147
|
+
|
|
148
|
+
// Create directory
|
|
149
|
+
await sandbox.filesystem.mkdir('/tmp/data');
|
|
107
150
|
|
|
108
151
|
// List directory contents
|
|
109
|
-
const
|
|
110
|
-
|
|
111
|
-
|
|
152
|
+
const files = await sandbox.filesystem.readdir('/tmp');
|
|
153
|
+
|
|
154
|
+
// Check if file exists
|
|
155
|
+
const exists = await sandbox.filesystem.exists('/tmp/hello.py');
|
|
156
|
+
|
|
157
|
+
// Remove file or directory
|
|
158
|
+
await sandbox.filesystem.remove('/tmp/hello.py');
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
### Terminal Operations
|
|
162
|
+
|
|
163
|
+
```typescript
|
|
164
|
+
// Create terminal
|
|
165
|
+
const terminal = await sandbox.terminal.create({
|
|
166
|
+
command: 'bash',
|
|
167
|
+
cols: 80,
|
|
168
|
+
rows: 24,
|
|
169
|
+
onData: (data: Uint8Array) => {
|
|
170
|
+
const output = new TextDecoder().decode(data);
|
|
171
|
+
console.log('Terminal output:', output);
|
|
172
|
+
}
|
|
112
173
|
});
|
|
113
174
|
|
|
114
|
-
//
|
|
115
|
-
await
|
|
175
|
+
// Write to terminal
|
|
176
|
+
await terminal.write('echo "Hello Terminal!"\n');
|
|
177
|
+
|
|
178
|
+
// Resize terminal
|
|
179
|
+
await terminal.resize(120, 30);
|
|
180
|
+
|
|
181
|
+
// Kill terminal
|
|
182
|
+
await terminal.kill();
|
|
183
|
+
|
|
184
|
+
// List all terminals
|
|
185
|
+
const terminals = await sandbox.terminal.list();
|
|
186
|
+
|
|
187
|
+
// Get terminal by ID
|
|
188
|
+
const existingTerminal = await sandbox.terminal.getById('terminal-id');
|
|
116
189
|
```
|
|
117
190
|
|
|
118
|
-
###
|
|
191
|
+
### Sandbox Management
|
|
119
192
|
|
|
120
193
|
```typescript
|
|
194
|
+
// Get sandbox info
|
|
195
|
+
const info = await sandbox.getInfo();
|
|
196
|
+
console.log(info.id, info.provider, info.status);
|
|
197
|
+
|
|
198
|
+
// Get existing sandbox (reconnect)
|
|
199
|
+
const existing = await compute.sandbox.getById(provider, 'sandbox-id');
|
|
200
|
+
|
|
201
|
+
// Destroy sandbox
|
|
202
|
+
await compute.sandbox.destroy(provider, 'sandbox-id');
|
|
203
|
+
|
|
204
|
+
// Note: E2B doesn't support listing all sandboxes
|
|
205
|
+
// Each sandbox is managed individually
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
## Runtime Detection
|
|
209
|
+
|
|
210
|
+
The provider automatically detects the runtime based on code patterns:
|
|
211
|
+
|
|
212
|
+
**Python indicators:**
|
|
213
|
+
- `print(` statements
|
|
214
|
+
- `import` statements
|
|
215
|
+
- `def` function definitions
|
|
216
|
+
- Python-specific syntax (`f"`, `__`, etc.)
|
|
217
|
+
|
|
218
|
+
**Default:** Node.js for all other cases
|
|
219
|
+
|
|
220
|
+
## Error Handling
|
|
221
|
+
|
|
222
|
+
```typescript
|
|
223
|
+
try {
|
|
224
|
+
const result = await sandbox.runCode('invalid code');
|
|
225
|
+
} catch (error) {
|
|
226
|
+
if (error.message.includes('Missing E2B API key')) {
|
|
227
|
+
console.error('Set E2B_API_KEY environment variable');
|
|
228
|
+
} else if (error.message.includes('Invalid E2B API key format')) {
|
|
229
|
+
console.error('E2B API keys should start with "e2b_"');
|
|
230
|
+
} else if (error.message.includes('authentication failed')) {
|
|
231
|
+
console.error('Check your E2B API key');
|
|
232
|
+
} else if (error.message.includes('quota exceeded')) {
|
|
233
|
+
console.error('E2B usage limits reached');
|
|
234
|
+
} else if (error.message.includes('Syntax error')) {
|
|
235
|
+
console.error('Code has syntax errors');
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
## Web Framework Integration
|
|
241
|
+
|
|
242
|
+
Use with web frameworks via the request handler:
|
|
243
|
+
|
|
244
|
+
```typescript
|
|
245
|
+
import { handleComputeRequest } from 'computesdk';
|
|
121
246
|
import { e2b } from '@computesdk/e2b';
|
|
122
247
|
|
|
123
|
-
|
|
248
|
+
export async function POST(request: Request) {
|
|
249
|
+
return handleComputeRequest({
|
|
250
|
+
request,
|
|
251
|
+
provider: e2b({ apiKey: process.env.E2B_API_KEY })
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
## Examples
|
|
257
|
+
|
|
258
|
+
### Data Science Workflow
|
|
259
|
+
|
|
260
|
+
```typescript
|
|
261
|
+
const sandbox = await compute.sandbox.create({});
|
|
124
262
|
|
|
125
263
|
// Create project structure
|
|
126
264
|
await sandbox.filesystem.mkdir('/analysis');
|
|
@@ -136,7 +274,7 @@ Charlie,35,Chicago`;
|
|
|
136
274
|
await sandbox.filesystem.writeFile('/analysis/data/people.csv', csvData);
|
|
137
275
|
|
|
138
276
|
// Process data with Python
|
|
139
|
-
const result = await sandbox.
|
|
277
|
+
const result = await sandbox.runCode(`
|
|
140
278
|
import pandas as pd
|
|
141
279
|
import matplotlib.pyplot as plt
|
|
142
280
|
|
|
@@ -183,251 +321,50 @@ const chartExists = await sandbox.filesystem.exists('/analysis/output/age_chart.
|
|
|
183
321
|
console.log('Chart created:', chartExists);
|
|
184
322
|
```
|
|
185
323
|
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
E2B supports interactive PTY terminals for real-time command execution:
|
|
189
|
-
|
|
190
|
-
### Basic Terminal Usage
|
|
324
|
+
### Interactive Terminal Session
|
|
191
325
|
|
|
192
326
|
```typescript
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
const sandbox = e2b();
|
|
327
|
+
const sandbox = await compute.sandbox.create({});
|
|
196
328
|
|
|
197
|
-
// Create
|
|
329
|
+
// Create interactive Python terminal
|
|
198
330
|
const terminal = await sandbox.terminal.create({
|
|
199
|
-
command: 'bash',
|
|
200
|
-
cols: 80,
|
|
201
|
-
rows: 24
|
|
202
|
-
});
|
|
203
|
-
|
|
204
|
-
console.log(`Terminal created with PID: ${terminal.pid}`);
|
|
205
|
-
|
|
206
|
-
// Write commands to terminal
|
|
207
|
-
await terminal.write('echo "Hello from terminal!"\n');
|
|
208
|
-
await terminal.write('ls -la\n');
|
|
209
|
-
await terminal.write('python --version\n');
|
|
210
|
-
|
|
211
|
-
// Set up data handler for terminal output
|
|
212
|
-
terminal.onData = (data: Uint8Array) => {
|
|
213
|
-
const output = new TextDecoder().decode(data);
|
|
214
|
-
console.log('Terminal output:', output);
|
|
215
|
-
};
|
|
216
|
-
|
|
217
|
-
// Resize terminal
|
|
218
|
-
await terminal.resize(120, 30);
|
|
219
|
-
|
|
220
|
-
// List all active terminals
|
|
221
|
-
const terminals = await sandbox.terminal.list();
|
|
222
|
-
console.log(`Active terminals: ${terminals.length}`);
|
|
223
|
-
|
|
224
|
-
// Clean up
|
|
225
|
-
await terminal.kill();
|
|
226
|
-
```
|
|
227
|
-
|
|
228
|
-
### Interactive Python Session
|
|
229
|
-
|
|
230
|
-
```typescript
|
|
231
|
-
const sandbox = e2b();
|
|
232
|
-
|
|
233
|
-
// Start Python interpreter in terminal
|
|
234
|
-
const pythonTerminal = await sandbox.terminal.create({
|
|
235
331
|
command: 'python3',
|
|
236
332
|
cols: 80,
|
|
237
|
-
rows: 24
|
|
333
|
+
rows: 24,
|
|
334
|
+
onData: (data: Uint8Array) => {
|
|
335
|
+
const output = new TextDecoder().decode(data);
|
|
336
|
+
process.stdout.write(output); // Forward to console
|
|
337
|
+
}
|
|
238
338
|
});
|
|
239
339
|
|
|
240
|
-
// Set up output handler
|
|
241
|
-
pythonTerminal.onData = (data: Uint8Array) => {
|
|
242
|
-
const output = new TextDecoder().decode(data);
|
|
243
|
-
process.stdout.write(output); // Forward to console
|
|
244
|
-
};
|
|
245
|
-
|
|
246
340
|
// Send Python commands
|
|
247
|
-
await
|
|
248
|
-
await
|
|
249
|
-
await
|
|
250
|
-
await
|
|
251
|
-
await
|
|
252
|
-
await
|
|
253
|
-
|
|
254
|
-
// Wait
|
|
341
|
+
await terminal.write('import numpy as np\n');
|
|
342
|
+
await terminal.write('import pandas as pd\n');
|
|
343
|
+
await terminal.write('print("Libraries loaded!")\n');
|
|
344
|
+
await terminal.write('data = np.array([1, 2, 3, 4, 5])\n');
|
|
345
|
+
await terminal.write('print(f"Mean: {data.mean()}")\n');
|
|
346
|
+
await terminal.write('exit()\n');
|
|
347
|
+
|
|
348
|
+
// Wait for commands to execute
|
|
255
349
|
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
256
350
|
|
|
257
|
-
await
|
|
258
|
-
```
|
|
259
|
-
|
|
260
|
-
## Command Execution
|
|
261
|
-
|
|
262
|
-
Execute shell commands directly with full output capture:
|
|
263
|
-
|
|
264
|
-
```typescript
|
|
265
|
-
import { e2b } from '@computesdk/e2b';
|
|
266
|
-
|
|
267
|
-
const sandbox = e2b();
|
|
268
|
-
|
|
269
|
-
// Run shell commands
|
|
270
|
-
const lsResult = await sandbox.runCommand('ls', ['-la', '/tmp']);
|
|
271
|
-
console.log('Directory listing:', lsResult.stdout);
|
|
272
|
-
|
|
273
|
-
// Install packages
|
|
274
|
-
const pipResult = await sandbox.runCommand('pip', ['install', 'requests']);
|
|
275
|
-
console.log('Package installation:', pipResult.stdout);
|
|
276
|
-
|
|
277
|
-
// Run complex commands
|
|
278
|
-
const gitResult = await sandbox.runCommand('git', ['--version']);
|
|
279
|
-
console.log('Git version:', gitResult.stdout);
|
|
280
|
-
|
|
281
|
-
// Check system info
|
|
282
|
-
const systemResult = await sandbox.runCommand('uname', ['-a']);
|
|
283
|
-
console.log('System info:', systemResult.stdout);
|
|
284
|
-
```
|
|
285
|
-
|
|
286
|
-
## Configuration
|
|
287
|
-
|
|
288
|
-
```typescript
|
|
289
|
-
import { e2b } from '@computesdk/e2b';
|
|
290
|
-
|
|
291
|
-
const sandbox = e2b({
|
|
292
|
-
timeout: 600000, // 10 minutes (default: 5 minutes)
|
|
293
|
-
runtime: 'python' // Only Python is supported
|
|
294
|
-
});
|
|
295
|
-
```
|
|
296
|
-
|
|
297
|
-
## API Reference
|
|
298
|
-
|
|
299
|
-
### Core Methods
|
|
300
|
-
|
|
301
|
-
#### `sandbox.execute(code: string, runtime?: Runtime): Promise<ExecutionResult>`
|
|
302
|
-
|
|
303
|
-
Execute Python code in the sandbox.
|
|
304
|
-
|
|
305
|
-
```typescript
|
|
306
|
-
const result = await sandbox.execute(`
|
|
307
|
-
x = 1 + 1
|
|
308
|
-
print(f"Result: {x}")
|
|
309
|
-
`);
|
|
310
|
-
// Returns: { stdout: "Result: 2", stderr: "", exitCode: 0, executionTime: 45 }
|
|
311
|
-
```
|
|
312
|
-
|
|
313
|
-
#### `sandbox.runCommand(command: string, args?: string[]): Promise<ExecutionResult>`
|
|
314
|
-
|
|
315
|
-
Execute shell commands.
|
|
316
|
-
|
|
317
|
-
```typescript
|
|
318
|
-
const result = await sandbox.runCommand('python', ['--version']);
|
|
319
|
-
// Returns: { stdout: "Python 3.11.0", stderr: "", exitCode: 0, executionTime: 12 }
|
|
320
|
-
```
|
|
321
|
-
|
|
322
|
-
#### `sandbox.getInfo(): Promise<SandboxInfo>`
|
|
323
|
-
|
|
324
|
-
Get sandbox information.
|
|
325
|
-
|
|
326
|
-
```typescript
|
|
327
|
-
const info = await sandbox.getInfo();
|
|
328
|
-
// Returns: { provider: "e2b", runtime: "python", status: "running", ... }
|
|
329
|
-
```
|
|
330
|
-
|
|
331
|
-
#### `sandbox.kill(): Promise<void>`
|
|
332
|
-
|
|
333
|
-
Terminate the sandbox and clean up resources.
|
|
334
|
-
|
|
335
|
-
```typescript
|
|
336
|
-
await sandbox.kill();
|
|
337
|
-
```
|
|
338
|
-
|
|
339
|
-
### Filesystem API
|
|
340
|
-
|
|
341
|
-
#### `sandbox.filesystem.readFile(path: string): Promise<string>`
|
|
342
|
-
|
|
343
|
-
Read file contents as text.
|
|
344
|
-
|
|
345
|
-
#### `sandbox.filesystem.writeFile(path: string, content: string): Promise<void>`
|
|
346
|
-
|
|
347
|
-
Write content to a file (creates file if it doesn't exist).
|
|
348
|
-
|
|
349
|
-
#### `sandbox.filesystem.mkdir(path: string): Promise<void>`
|
|
350
|
-
|
|
351
|
-
Create directory and parent directories if needed.
|
|
352
|
-
|
|
353
|
-
#### `sandbox.filesystem.readdir(path: string): Promise<FileEntry[]>`
|
|
354
|
-
|
|
355
|
-
List directory contents with metadata.
|
|
356
|
-
|
|
357
|
-
#### `sandbox.filesystem.exists(path: string): Promise<boolean>`
|
|
358
|
-
|
|
359
|
-
Check if file or directory exists.
|
|
360
|
-
|
|
361
|
-
#### `sandbox.filesystem.remove(path: string): Promise<void>`
|
|
362
|
-
|
|
363
|
-
Remove file or directory.
|
|
364
|
-
|
|
365
|
-
### Terminal API
|
|
366
|
-
|
|
367
|
-
#### `sandbox.terminal.create(options?: TerminalCreateOptions): Promise<InteractiveTerminalSession>`
|
|
368
|
-
|
|
369
|
-
Create a new PTY terminal session.
|
|
370
|
-
|
|
371
|
-
```typescript
|
|
372
|
-
const terminal = await sandbox.terminal.create({
|
|
373
|
-
command: 'bash', // Command to run (default: 'bash')
|
|
374
|
-
cols: 80, // Terminal width (default: 80)
|
|
375
|
-
rows: 24 // Terminal height (default: 24)
|
|
376
|
-
});
|
|
377
|
-
```
|
|
378
|
-
|
|
379
|
-
#### `sandbox.terminal.list(): Promise<InteractiveTerminalSession[]>`
|
|
380
|
-
|
|
381
|
-
List all active terminal sessions.
|
|
382
|
-
|
|
383
|
-
#### Terminal Session Methods
|
|
384
|
-
|
|
385
|
-
- `terminal.write(data: string | Uint8Array): Promise<void>` - Send input to terminal
|
|
386
|
-
- `terminal.resize(cols: number, rows: number): Promise<void>` - Resize terminal
|
|
387
|
-
- `terminal.kill(): Promise<void>` - Terminate terminal session
|
|
388
|
-
- `terminal.onData: (data: Uint8Array) => void` - Output data handler
|
|
389
|
-
|
|
390
|
-
## Error Handling
|
|
391
|
-
|
|
392
|
-
```typescript
|
|
393
|
-
import { e2b } from '@computesdk/e2b';
|
|
394
|
-
|
|
395
|
-
try {
|
|
396
|
-
const sandbox = e2b();
|
|
397
|
-
const result = await sandbox.execute('invalid python code');
|
|
398
|
-
} catch (error) {
|
|
399
|
-
if (error.message.includes('Missing E2B API key')) {
|
|
400
|
-
console.error('Set E2B_API_KEY environment variable');
|
|
401
|
-
} else if (error.message.includes('Invalid E2B API key format')) {
|
|
402
|
-
console.error('E2B API keys should start with "e2b_"');
|
|
403
|
-
} else if (error.message.includes('authentication failed')) {
|
|
404
|
-
console.error('Check your E2B API key');
|
|
405
|
-
} else if (error.message.includes('quota exceeded')) {
|
|
406
|
-
console.error('E2B usage quota exceeded');
|
|
407
|
-
} else if (error.message.includes('timeout')) {
|
|
408
|
-
console.error('Execution timed out - consider increasing timeout');
|
|
409
|
-
} else if (error.message.includes('memory limits')) {
|
|
410
|
-
console.error('Memory limit exceeded - optimize your code');
|
|
411
|
-
}
|
|
412
|
-
}
|
|
351
|
+
await terminal.kill();
|
|
413
352
|
```
|
|
414
353
|
|
|
415
|
-
## Examples
|
|
416
|
-
|
|
417
354
|
### Machine Learning Pipeline
|
|
418
355
|
|
|
419
356
|
```typescript
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
357
|
+
const sandbox = await compute.sandbox.create({
|
|
358
|
+
options: { timeout: 600000 } // 10 minutes for ML tasks
|
|
359
|
+
});
|
|
423
360
|
|
|
424
361
|
// Create ML project structure
|
|
425
362
|
await sandbox.filesystem.mkdir('/ml-project');
|
|
426
363
|
await sandbox.filesystem.mkdir('/ml-project/data');
|
|
427
364
|
await sandbox.filesystem.mkdir('/ml-project/models');
|
|
428
365
|
|
|
429
|
-
// Generate
|
|
430
|
-
const result = await sandbox.
|
|
366
|
+
// Generate and process data
|
|
367
|
+
const result = await sandbox.runCode(`
|
|
431
368
|
import numpy as np
|
|
432
369
|
import pandas as pd
|
|
433
370
|
from sklearn.model_selection import train_test_split
|
|
@@ -501,99 +438,24 @@ console.log('ML Results:', JSON.parse(results));
|
|
|
501
438
|
// Verify model file exists
|
|
502
439
|
const modelExists = await sandbox.filesystem.exists('/ml-project/models/linear_model.pkl');
|
|
503
440
|
console.log('Model saved:', modelExists);
|
|
504
|
-
|
|
505
|
-
await sandbox.kill();
|
|
506
|
-
```
|
|
507
|
-
|
|
508
|
-
### Web Scraping and Analysis
|
|
509
|
-
|
|
510
|
-
```typescript
|
|
511
|
-
import { e2b } from '@computesdk/e2b';
|
|
512
|
-
|
|
513
|
-
const sandbox = e2b();
|
|
514
|
-
|
|
515
|
-
// Install required packages and scrape data
|
|
516
|
-
const result = await sandbox.execute(`
|
|
517
|
-
import subprocess
|
|
518
|
-
import sys
|
|
519
|
-
|
|
520
|
-
# Install required packages
|
|
521
|
-
subprocess.check_call([sys.executable, '-m', 'pip', 'install', 'requests', 'beautifulsoup4'])
|
|
522
|
-
|
|
523
|
-
import requests
|
|
524
|
-
from bs4 import BeautifulSoup
|
|
525
|
-
import json
|
|
526
|
-
import pandas as pd
|
|
527
|
-
|
|
528
|
-
# Example: Scrape Python.org news (respecting robots.txt)
|
|
529
|
-
url = 'https://www.python.org/jobs/'
|
|
530
|
-
headers = {'User-Agent': 'Mozilla/5.0 (compatible; ComputeSDK/1.0)'}
|
|
531
|
-
|
|
532
|
-
try:
|
|
533
|
-
response = requests.get(url, headers=headers, timeout=10)
|
|
534
|
-
response.raise_for_status()
|
|
535
|
-
|
|
536
|
-
soup = BeautifulSoup(response.content, 'html.parser')
|
|
537
|
-
|
|
538
|
-
# Extract job listings (example structure)
|
|
539
|
-
jobs = []
|
|
540
|
-
job_elements = soup.find_all('h2', class_='listing-company-name')[:5] # Limit to 5
|
|
541
|
-
|
|
542
|
-
for job_elem in job_elements:
|
|
543
|
-
job_title = job_elem.get_text(strip=True)
|
|
544
|
-
jobs.append({'title': job_title, 'source': 'python.org'})
|
|
545
|
-
|
|
546
|
-
print(f"Found {len(jobs)} job listings:")
|
|
547
|
-
for i, job in enumerate(jobs, 1):
|
|
548
|
-
print(f"{i}. {job['title']}")
|
|
549
|
-
|
|
550
|
-
# Save data
|
|
551
|
-
with open('/tmp/jobs.json', 'w') as f:
|
|
552
|
-
json.dump(jobs, f, indent=2)
|
|
553
|
-
|
|
554
|
-
print("\\nData saved to /tmp/jobs.json")
|
|
555
|
-
|
|
556
|
-
except Exception as e:
|
|
557
|
-
print(f"Error scraping data: {e}")
|
|
558
|
-
# Create sample data instead
|
|
559
|
-
jobs = [
|
|
560
|
-
{'title': 'Senior Python Developer', 'source': 'example.com'},
|
|
561
|
-
{'title': 'Data Scientist', 'source': 'example.com'},
|
|
562
|
-
{'title': 'Backend Engineer', 'source': 'example.com'}
|
|
563
|
-
]
|
|
564
|
-
|
|
565
|
-
with open('/tmp/jobs.json', 'w') as f:
|
|
566
|
-
json.dump(jobs, f, indent=2)
|
|
567
|
-
|
|
568
|
-
print("Created sample data instead")
|
|
569
|
-
`);
|
|
570
|
-
|
|
571
|
-
console.log(result.stdout);
|
|
572
|
-
|
|
573
|
-
// Read the scraped data
|
|
574
|
-
const jobsData = await sandbox.filesystem.readFile('/tmp/jobs.json');
|
|
575
|
-
console.log('Scraped jobs:', JSON.parse(jobsData));
|
|
576
|
-
|
|
577
|
-
await sandbox.kill();
|
|
578
441
|
```
|
|
579
442
|
|
|
580
443
|
## Best Practices
|
|
581
444
|
|
|
582
|
-
1. **Resource Management**: Always
|
|
445
|
+
1. **Resource Management**: Always destroy sandboxes when done to free resources
|
|
583
446
|
2. **Error Handling**: Use try-catch blocks for robust error handling
|
|
584
447
|
3. **Timeouts**: Set appropriate timeouts for long-running tasks
|
|
585
|
-
4. **File Organization**: Use the filesystem API to organize
|
|
448
|
+
4. **File Organization**: Use the filesystem API to organize project files
|
|
586
449
|
5. **Terminal Sessions**: Clean up terminal sessions with `terminal.kill()`
|
|
587
|
-
6. **
|
|
588
|
-
7. **API Quotas**: Keep track of your E2B usage and quotas
|
|
450
|
+
6. **API Key Security**: Never commit API keys to version control
|
|
589
451
|
|
|
590
452
|
## Limitations
|
|
591
453
|
|
|
592
|
-
- **
|
|
454
|
+
- **Sandbox Listing**: E2B doesn't support listing all sandboxes (each is managed individually)
|
|
593
455
|
- **Memory Limits**: Subject to E2B sandbox memory constraints
|
|
594
456
|
- **Network Access**: Limited outbound network access
|
|
595
|
-
- **Execution Time**: Default 5-minute timeout (configurable up to E2B limits)
|
|
596
457
|
- **File Persistence**: Files are not persisted between sandbox sessions
|
|
458
|
+
- **Execution Time**: Subject to E2B timeout limits
|
|
597
459
|
|
|
598
460
|
## Support
|
|
599
461
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@computesdk/e2b",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.1",
|
|
4
4
|
"description": "E2B provider for ComputeSDK",
|
|
5
5
|
"author": "Garrison",
|
|
6
6
|
"license": "MIT",
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
],
|
|
20
20
|
"dependencies": {
|
|
21
21
|
"@e2b/code-interpreter": "^1.5.1",
|
|
22
|
-
"computesdk": "1.1.
|
|
22
|
+
"computesdk": "1.1.1"
|
|
23
23
|
},
|
|
24
24
|
"keywords": [
|
|
25
25
|
"e2b",
|