@computesdk/e2b 1.0.0 → 1.1.0
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 +483 -119
- package/dist/index.d.mts +17 -16
- package/dist/index.d.ts +17 -16
- package/dist/index.js +271 -103
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +271 -102
- package/dist/index.mjs.map +1 -1
- package/package.json +7 -8
package/README.md
CHANGED
|
@@ -1,6 +1,15 @@
|
|
|
1
1
|
# @computesdk/e2b
|
|
2
2
|
|
|
3
|
-
E2B provider for ComputeSDK - Execute Python code in secure, isolated E2B sandboxes.
|
|
3
|
+
E2B provider for ComputeSDK - Execute Python code with full filesystem and terminal support in secure, isolated E2B sandboxes.
|
|
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
|
|
4
13
|
|
|
5
14
|
## Installation
|
|
6
15
|
|
|
@@ -17,225 +26,580 @@ npm install @computesdk/e2b
|
|
|
17
26
|
export E2B_API_KEY=e2b_your_api_key_here
|
|
18
27
|
```
|
|
19
28
|
|
|
20
|
-
##
|
|
29
|
+
## Quick Start
|
|
21
30
|
|
|
22
|
-
### Basic
|
|
31
|
+
### Basic Code Execution
|
|
23
32
|
|
|
24
33
|
```typescript
|
|
25
34
|
import { e2b } from '@computesdk/e2b';
|
|
26
35
|
|
|
27
|
-
const
|
|
36
|
+
const sandbox = e2b();
|
|
28
37
|
|
|
29
38
|
// Execute Python code
|
|
30
|
-
const result = await
|
|
39
|
+
const result = await sandbox.execute(`
|
|
40
|
+
import pandas as pd
|
|
41
|
+
import numpy as np
|
|
42
|
+
|
|
43
|
+
data = {'A': [1, 2, 3], 'B': [4, 5, 6]}
|
|
44
|
+
df = pd.DataFrame(data)
|
|
45
|
+
print(df)
|
|
46
|
+
print(f"Sum: {df.sum().sum()}")
|
|
47
|
+
`);
|
|
48
|
+
|
|
49
|
+
console.log(result.stdout);
|
|
50
|
+
// Output:
|
|
51
|
+
// A B
|
|
52
|
+
// 0 1 4
|
|
53
|
+
// 1 2 5
|
|
54
|
+
// 2 3 6
|
|
55
|
+
// Sum: 21
|
|
56
|
+
|
|
57
|
+
await sandbox.kill();
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### With ComputeSDK Auto-Detection
|
|
61
|
+
|
|
62
|
+
```typescript
|
|
63
|
+
import { ComputeSDK } from 'computesdk';
|
|
64
|
+
|
|
65
|
+
// Automatically uses E2B if E2B_API_KEY is set
|
|
66
|
+
const sandbox = ComputeSDK.createSandbox();
|
|
67
|
+
|
|
68
|
+
const result = await sandbox.execute('print("Hello from E2B!")');
|
|
31
69
|
console.log(result.stdout); // "Hello from E2B!"
|
|
32
70
|
```
|
|
33
71
|
|
|
34
|
-
|
|
72
|
+
## Filesystem Operations
|
|
73
|
+
|
|
74
|
+
E2B provides full filesystem access through the `sandbox.filesystem` interface:
|
|
75
|
+
|
|
76
|
+
### File Operations
|
|
35
77
|
|
|
36
78
|
```typescript
|
|
37
|
-
import { executeSandbox } from 'computesdk';
|
|
38
79
|
import { e2b } from '@computesdk/e2b';
|
|
39
80
|
|
|
40
|
-
const
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
81
|
+
const sandbox = e2b();
|
|
82
|
+
|
|
83
|
+
// Write a file
|
|
84
|
+
await sandbox.filesystem.writeFile('/tmp/data.json', JSON.stringify({
|
|
85
|
+
name: 'ComputeSDK',
|
|
86
|
+
version: '1.0.0'
|
|
87
|
+
}));
|
|
88
|
+
|
|
89
|
+
// Read the file
|
|
90
|
+
const content = await sandbox.filesystem.readFile('/tmp/data.json');
|
|
91
|
+
console.log(JSON.parse(content)); // { name: 'ComputeSDK', version: '1.0.0' }
|
|
92
|
+
|
|
93
|
+
// Check if file exists
|
|
94
|
+
const exists = await sandbox.filesystem.exists('/tmp/data.json');
|
|
95
|
+
console.log(exists); // true
|
|
96
|
+
|
|
97
|
+
// Remove the file
|
|
98
|
+
await sandbox.filesystem.remove('/tmp/data.json');
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### Directory Operations
|
|
102
|
+
|
|
103
|
+
```typescript
|
|
104
|
+
// Create directories
|
|
105
|
+
await sandbox.filesystem.mkdir('/project/data');
|
|
106
|
+
await sandbox.filesystem.mkdir('/project/output');
|
|
107
|
+
|
|
108
|
+
// List directory contents
|
|
109
|
+
const entries = await sandbox.filesystem.readdir('/project');
|
|
110
|
+
entries.forEach(entry => {
|
|
111
|
+
console.log(`${entry.name} (${entry.isDirectory ? 'dir' : 'file'}) - ${entry.size} bytes`);
|
|
44
112
|
});
|
|
113
|
+
|
|
114
|
+
// Remove directory
|
|
115
|
+
await sandbox.filesystem.remove('/project/data');
|
|
45
116
|
```
|
|
46
117
|
|
|
47
|
-
###
|
|
118
|
+
### Data Science Workflow
|
|
48
119
|
|
|
49
120
|
```typescript
|
|
50
121
|
import { e2b } from '@computesdk/e2b';
|
|
51
122
|
|
|
52
|
-
const
|
|
53
|
-
timeout: 300000, // 5 minutes (default)
|
|
54
|
-
runtime: 'python' // Only Python is supported
|
|
55
|
-
});
|
|
56
|
-
```
|
|
123
|
+
const sandbox = e2b();
|
|
57
124
|
|
|
58
|
-
|
|
125
|
+
// Create project structure
|
|
126
|
+
await sandbox.filesystem.mkdir('/analysis');
|
|
127
|
+
await sandbox.filesystem.mkdir('/analysis/data');
|
|
128
|
+
await sandbox.filesystem.mkdir('/analysis/output');
|
|
129
|
+
|
|
130
|
+
// Write input data
|
|
131
|
+
const csvData = `name,age,city
|
|
132
|
+
Alice,25,New York
|
|
133
|
+
Bob,30,San Francisco
|
|
134
|
+
Charlie,35,Chicago`;
|
|
135
|
+
|
|
136
|
+
await sandbox.filesystem.writeFile('/analysis/data/people.csv', csvData);
|
|
59
137
|
|
|
60
|
-
|
|
138
|
+
// Process data with Python
|
|
139
|
+
const result = await sandbox.execute(`
|
|
140
|
+
import pandas as pd
|
|
141
|
+
import matplotlib.pyplot as plt
|
|
61
142
|
|
|
62
|
-
|
|
143
|
+
# Read data
|
|
144
|
+
df = pd.read_csv('/analysis/data/people.csv')
|
|
145
|
+
print("Data loaded:")
|
|
146
|
+
print(df)
|
|
63
147
|
|
|
64
|
-
|
|
148
|
+
# Calculate statistics
|
|
149
|
+
avg_age = df['age'].mean()
|
|
150
|
+
print(f"\\nAverage age: {avg_age}")
|
|
151
|
+
|
|
152
|
+
# Create visualization
|
|
153
|
+
plt.figure(figsize=(8, 6))
|
|
154
|
+
plt.bar(df['name'], df['age'])
|
|
155
|
+
plt.title('Age by Person')
|
|
156
|
+
plt.xlabel('Name')
|
|
157
|
+
plt.ylabel('Age')
|
|
158
|
+
plt.savefig('/analysis/output/age_chart.png')
|
|
159
|
+
print("\\nChart saved to /analysis/output/age_chart.png")
|
|
160
|
+
|
|
161
|
+
# Save results
|
|
162
|
+
results = {
|
|
163
|
+
'total_people': len(df),
|
|
164
|
+
'average_age': avg_age,
|
|
165
|
+
'cities': df['city'].unique().tolist()
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
import json
|
|
169
|
+
with open('/analysis/output/results.json', 'w') as f:
|
|
170
|
+
json.dump(results, f, indent=2)
|
|
171
|
+
|
|
172
|
+
print("Results saved!")
|
|
173
|
+
`);
|
|
65
174
|
|
|
66
|
-
|
|
67
|
-
- `timeout`: Execution timeout in milliseconds (default: 300000)
|
|
68
|
-
- `runtime`: Runtime environment - only `'python'` is supported
|
|
175
|
+
console.log(result.stdout);
|
|
69
176
|
|
|
70
|
-
|
|
177
|
+
// Read the results
|
|
178
|
+
const results = await sandbox.filesystem.readFile('/analysis/output/results.json');
|
|
179
|
+
console.log('Analysis results:', JSON.parse(results));
|
|
71
180
|
|
|
72
|
-
|
|
181
|
+
// Check if chart was created
|
|
182
|
+
const chartExists = await sandbox.filesystem.exists('/analysis/output/age_chart.png');
|
|
183
|
+
console.log('Chart created:', chartExists);
|
|
184
|
+
```
|
|
73
185
|
|
|
74
|
-
|
|
186
|
+
## Terminal Operations
|
|
75
187
|
|
|
76
|
-
|
|
188
|
+
E2B supports interactive PTY terminals for real-time command execution:
|
|
77
189
|
|
|
78
|
-
|
|
190
|
+
### Basic Terminal Usage
|
|
79
191
|
|
|
80
192
|
```typescript
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
193
|
+
import { e2b } from '@computesdk/e2b';
|
|
194
|
+
|
|
195
|
+
const sandbox = e2b();
|
|
196
|
+
|
|
197
|
+
// Create a new terminal session
|
|
198
|
+
const terminal = await sandbox.terminal.create({
|
|
199
|
+
command: 'bash',
|
|
200
|
+
cols: 80,
|
|
201
|
+
rows: 24
|
|
202
|
+
});
|
|
86
203
|
|
|
87
|
-
|
|
204
|
+
console.log(`Terminal created with PID: ${terminal.pid}`);
|
|
88
205
|
|
|
89
|
-
|
|
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
|
|
90
229
|
|
|
91
230
|
```typescript
|
|
92
|
-
|
|
231
|
+
const sandbox = e2b();
|
|
232
|
+
|
|
233
|
+
// Start Python interpreter in terminal
|
|
234
|
+
const pythonTerminal = await sandbox.terminal.create({
|
|
235
|
+
command: 'python3',
|
|
236
|
+
cols: 80,
|
|
237
|
+
rows: 24
|
|
238
|
+
});
|
|
239
|
+
|
|
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
|
+
// Send Python commands
|
|
247
|
+
await pythonTerminal.write('import numpy as np\n');
|
|
248
|
+
await pythonTerminal.write('import pandas as pd\n');
|
|
249
|
+
await pythonTerminal.write('print("Libraries loaded!")\n');
|
|
250
|
+
await pythonTerminal.write('data = np.array([1, 2, 3, 4, 5])\n');
|
|
251
|
+
await pythonTerminal.write('print(f"Mean: {data.mean()}")\n');
|
|
252
|
+
await pythonTerminal.write('exit()\n');
|
|
253
|
+
|
|
254
|
+
// Wait a moment for commands to execute
|
|
255
|
+
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
256
|
+
|
|
257
|
+
await pythonTerminal.kill();
|
|
93
258
|
```
|
|
94
259
|
|
|
95
|
-
|
|
260
|
+
## Command Execution
|
|
96
261
|
|
|
97
|
-
|
|
262
|
+
Execute shell commands directly with full output capture:
|
|
98
263
|
|
|
99
264
|
```typescript
|
|
100
|
-
|
|
101
|
-
// info.provider: "e2b"
|
|
102
|
-
// info.runtime: "python"
|
|
103
|
-
// info.status: "running" | "stopped"
|
|
104
|
-
```
|
|
265
|
+
import { e2b } from '@computesdk/e2b';
|
|
105
266
|
|
|
106
|
-
|
|
267
|
+
const sandbox = e2b();
|
|
107
268
|
|
|
108
|
-
|
|
269
|
+
// Run shell commands
|
|
270
|
+
const lsResult = await sandbox.runCommand('ls', ['-la', '/tmp']);
|
|
271
|
+
console.log('Directory listing:', lsResult.stdout);
|
|
109
272
|
|
|
110
|
-
|
|
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
|
|
111
287
|
|
|
112
288
|
```typescript
|
|
113
|
-
|
|
114
|
-
|
|
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>`
|
|
115
302
|
|
|
116
|
-
|
|
117
|
-
Error: Invalid E2B API key format. E2B API keys should start with 'e2b_'. Check your E2B_API_KEY environment variable.
|
|
303
|
+
Execute Python code in the sandbox.
|
|
118
304
|
|
|
119
|
-
|
|
120
|
-
|
|
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 }
|
|
121
311
|
```
|
|
122
312
|
|
|
123
|
-
|
|
313
|
+
#### `sandbox.runCommand(command: string, args?: string[]): Promise<ExecutionResult>`
|
|
314
|
+
|
|
315
|
+
Execute shell commands.
|
|
124
316
|
|
|
125
317
|
```typescript
|
|
126
|
-
|
|
127
|
-
|
|
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>`
|
|
128
323
|
|
|
129
|
-
|
|
130
|
-
Error: E2B execution timeout (300000ms). Consider increasing the timeout or optimizing your code.
|
|
324
|
+
Get sandbox information.
|
|
131
325
|
|
|
132
|
-
|
|
133
|
-
|
|
326
|
+
```typescript
|
|
327
|
+
const info = await sandbox.getInfo();
|
|
328
|
+
// Returns: { provider: "e2b", runtime: "python", status: "running", ... }
|
|
134
329
|
```
|
|
135
330
|
|
|
136
|
-
|
|
331
|
+
#### `sandbox.kill(): Promise<void>`
|
|
332
|
+
|
|
333
|
+
Terminate the sandbox and clean up resources.
|
|
137
334
|
|
|
138
335
|
```typescript
|
|
139
|
-
|
|
140
|
-
Error: E2B quota exceeded. Please check your usage at https://e2b.dev/
|
|
336
|
+
await sandbox.kill();
|
|
141
337
|
```
|
|
142
338
|
|
|
143
|
-
|
|
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[]>`
|
|
144
354
|
|
|
145
|
-
|
|
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.
|
|
146
370
|
|
|
147
371
|
```typescript
|
|
148
|
-
|
|
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
|
+
```
|
|
149
378
|
|
|
150
|
-
|
|
379
|
+
#### `sandbox.terminal.list(): Promise<InteractiveTerminalSession[]>`
|
|
151
380
|
|
|
152
|
-
|
|
153
|
-
import pandas as pd
|
|
154
|
-
import numpy as np
|
|
381
|
+
List all active terminal sessions.
|
|
155
382
|
|
|
156
|
-
|
|
157
|
-
data = {'A': [1, 2, 3], 'B': [4, 5, 6]}
|
|
158
|
-
df = pd.DataFrame(data)
|
|
383
|
+
#### Terminal Session Methods
|
|
159
384
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
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
|
|
164
389
|
|
|
165
|
-
|
|
166
|
-
|
|
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
|
+
}
|
|
167
413
|
```
|
|
168
414
|
|
|
169
|
-
|
|
415
|
+
## Examples
|
|
416
|
+
|
|
417
|
+
### Machine Learning Pipeline
|
|
170
418
|
|
|
171
419
|
```typescript
|
|
172
420
|
import { e2b } from '@computesdk/e2b';
|
|
173
421
|
|
|
174
|
-
const
|
|
422
|
+
const sandbox = e2b({ timeout: 600000 }); // 10 minutes for ML tasks
|
|
175
423
|
|
|
176
|
-
|
|
177
|
-
|
|
424
|
+
// Create ML project structure
|
|
425
|
+
await sandbox.filesystem.mkdir('/ml-project');
|
|
426
|
+
await sandbox.filesystem.mkdir('/ml-project/data');
|
|
427
|
+
await sandbox.filesystem.mkdir('/ml-project/models');
|
|
428
|
+
|
|
429
|
+
// Generate sample data
|
|
430
|
+
const result = await sandbox.execute(`
|
|
178
431
|
import numpy as np
|
|
432
|
+
import pandas as pd
|
|
433
|
+
from sklearn.model_selection import train_test_split
|
|
434
|
+
from sklearn.linear_model import LinearRegression
|
|
435
|
+
from sklearn.metrics import mean_squared_error, r2_score
|
|
436
|
+
import joblib
|
|
437
|
+
|
|
438
|
+
# Generate sample dataset
|
|
439
|
+
np.random.seed(42)
|
|
440
|
+
X = np.random.randn(1000, 5)
|
|
441
|
+
y = X.sum(axis=1) + np.random.randn(1000) * 0.1
|
|
442
|
+
|
|
443
|
+
# Create DataFrame
|
|
444
|
+
feature_names = [f'feature_{i}' for i in range(5)]
|
|
445
|
+
df = pd.DataFrame(X, columns=feature_names)
|
|
446
|
+
df['target'] = y
|
|
447
|
+
|
|
448
|
+
print(f"Dataset shape: {df.shape}")
|
|
449
|
+
print("\\nDataset info:")
|
|
450
|
+
print(df.describe())
|
|
179
451
|
|
|
180
|
-
#
|
|
181
|
-
|
|
182
|
-
|
|
452
|
+
# Save dataset
|
|
453
|
+
df.to_csv('/ml-project/data/dataset.csv', index=False)
|
|
454
|
+
print("\\nDataset saved to /ml-project/data/dataset.csv")
|
|
455
|
+
|
|
456
|
+
# Split data
|
|
457
|
+
X_train, X_test, y_train, y_test = train_test_split(
|
|
458
|
+
df[feature_names], df['target'], test_size=0.2, random_state=42
|
|
459
|
+
)
|
|
183
460
|
|
|
184
461
|
# Train model
|
|
185
462
|
model = LinearRegression()
|
|
186
|
-
model.fit(
|
|
463
|
+
model.fit(X_train, y_train)
|
|
464
|
+
|
|
465
|
+
# Make predictions
|
|
466
|
+
y_pred = model.predict(X_test)
|
|
467
|
+
|
|
468
|
+
# Evaluate
|
|
469
|
+
mse = mean_squared_error(y_test, y_pred)
|
|
470
|
+
r2 = r2_score(y_test, y_pred)
|
|
471
|
+
|
|
472
|
+
print(f"\\nModel Performance:")
|
|
473
|
+
print(f"MSE: {mse:.4f}")
|
|
474
|
+
print(f"R²: {r2:.4f}")
|
|
187
475
|
|
|
188
|
-
#
|
|
189
|
-
|
|
190
|
-
print(
|
|
191
|
-
`;
|
|
476
|
+
# Save model
|
|
477
|
+
joblib.dump(model, '/ml-project/models/linear_model.pkl')
|
|
478
|
+
print("\\nModel saved to /ml-project/models/linear_model.pkl")
|
|
192
479
|
|
|
193
|
-
|
|
194
|
-
|
|
480
|
+
# Save results
|
|
481
|
+
results = {
|
|
482
|
+
'mse': mse,
|
|
483
|
+
'r2': r2,
|
|
484
|
+
'feature_importance': dict(zip(feature_names, model.coef_)),
|
|
485
|
+
'intercept': model.intercept_
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
import json
|
|
489
|
+
with open('/ml-project/results.json', 'w') as f:
|
|
490
|
+
json.dump(results, f, indent=2)
|
|
491
|
+
|
|
492
|
+
print("Results saved!")
|
|
493
|
+
`);
|
|
494
|
+
|
|
495
|
+
console.log(result.stdout);
|
|
496
|
+
|
|
497
|
+
// Read the results
|
|
498
|
+
const results = await sandbox.filesystem.readFile('/ml-project/results.json');
|
|
499
|
+
console.log('ML Results:', JSON.parse(results));
|
|
500
|
+
|
|
501
|
+
// Verify model file exists
|
|
502
|
+
const modelExists = await sandbox.filesystem.exists('/ml-project/models/linear_model.pkl');
|
|
503
|
+
console.log('Model saved:', modelExists);
|
|
504
|
+
|
|
505
|
+
await sandbox.kill();
|
|
195
506
|
```
|
|
196
507
|
|
|
197
|
-
###
|
|
508
|
+
### Web Scraping and Analysis
|
|
198
509
|
|
|
199
510
|
```typescript
|
|
200
511
|
import { e2b } from '@computesdk/e2b';
|
|
201
512
|
|
|
202
|
-
const
|
|
513
|
+
const sandbox = e2b();
|
|
203
514
|
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
515
|
+
// Install required packages and scrape data
|
|
516
|
+
const result = await sandbox.execute(`
|
|
517
|
+
import subprocess
|
|
518
|
+
import sys
|
|
208
519
|
|
|
209
|
-
#
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
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
|
+
`);
|
|
214
570
|
|
|
215
|
-
const result = await provider.doExecute(code);
|
|
216
571
|
console.log(result.stdout);
|
|
217
|
-
```
|
|
218
572
|
|
|
219
|
-
|
|
573
|
+
// Read the scraped data
|
|
574
|
+
const jobsData = await sandbox.filesystem.readFile('/tmp/jobs.json');
|
|
575
|
+
console.log('Scraped jobs:', JSON.parse(jobsData));
|
|
220
576
|
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
- **Memory**: Subject to E2B sandbox memory limits
|
|
224
|
-
- **Network**: Limited network access in sandboxes
|
|
577
|
+
await sandbox.kill();
|
|
578
|
+
```
|
|
225
579
|
|
|
226
580
|
## Best Practices
|
|
227
581
|
|
|
228
|
-
1. **
|
|
229
|
-
2. **
|
|
230
|
-
3. **
|
|
231
|
-
4. **
|
|
232
|
-
5. **
|
|
582
|
+
1. **Resource Management**: Always call `sandbox.kill()` when done to free resources
|
|
583
|
+
2. **Error Handling**: Use try-catch blocks for robust error handling
|
|
584
|
+
3. **Timeouts**: Set appropriate timeouts for long-running tasks
|
|
585
|
+
4. **File Organization**: Use the filesystem API to organize your project files
|
|
586
|
+
5. **Terminal Sessions**: Clean up terminal sessions with `terminal.kill()`
|
|
587
|
+
6. **Memory Usage**: Monitor memory usage for large datasets
|
|
588
|
+
7. **API Quotas**: Keep track of your E2B usage and quotas
|
|
589
|
+
|
|
590
|
+
## Limitations
|
|
591
|
+
|
|
592
|
+
- **Python Only**: Currently only supports Python runtime
|
|
593
|
+
- **Memory Limits**: Subject to E2B sandbox memory constraints
|
|
594
|
+
- **Network Access**: Limited outbound network access
|
|
595
|
+
- **Execution Time**: Default 5-minute timeout (configurable up to E2B limits)
|
|
596
|
+
- **File Persistence**: Files are not persisted between sandbox sessions
|
|
233
597
|
|
|
234
598
|
## Support
|
|
235
599
|
|
|
236
|
-
- E2B Documentation
|
|
237
|
-
- ComputeSDK Issues
|
|
238
|
-
-
|
|
600
|
+
- [E2B Documentation](https://e2b.dev/docs)
|
|
601
|
+
- [ComputeSDK Issues](https://github.com/computesdk/computesdk/issues)
|
|
602
|
+
- [E2B Support](https://e2b.dev/support)
|
|
239
603
|
|
|
240
604
|
## License
|
|
241
605
|
|