grasp-sdk 0.1.3__tar.gz → 0.1.5__tar.gz

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.

Potentially problematic release.


This version of grasp-sdk might be problematic. Click here for more details.

Files changed (30) hide show
  1. {grasp_sdk-0.1.3/grasp_sdk.egg-info → grasp_sdk-0.1.5}/PKG-INFO +21 -3
  2. {grasp_sdk-0.1.3 → grasp_sdk-0.1.5}/README.md +20 -2
  3. {grasp_sdk-0.1.3 → grasp_sdk-0.1.5}/grasp_sdk/__init__.py +15 -3
  4. {grasp_sdk-0.1.3 → grasp_sdk-0.1.5}/grasp_sdk/sandbox/chrome-stable.mjs +48 -13
  5. {grasp_sdk-0.1.3 → grasp_sdk-0.1.5}/grasp_sdk/sandbox/chromium.mjs +24 -15
  6. {grasp_sdk-0.1.3 → grasp_sdk-0.1.5/grasp_sdk.egg-info}/PKG-INFO +21 -3
  7. {grasp_sdk-0.1.3 → grasp_sdk-0.1.5}/grasp_sdk.egg-info/SOURCES.txt +0 -1
  8. {grasp_sdk-0.1.3 → grasp_sdk-0.1.5}/pyproject.toml +1 -1
  9. grasp_sdk-0.1.3/grasp_sdk/sandbox/jsconfig.json +0 -22
  10. {grasp_sdk-0.1.3 → grasp_sdk-0.1.5}/MANIFEST.in +0 -0
  11. {grasp_sdk-0.1.3 → grasp_sdk-0.1.5}/build_and_publish.py +0 -0
  12. {grasp_sdk-0.1.3 → grasp_sdk-0.1.5}/example_usage.py +0 -0
  13. {grasp_sdk-0.1.3 → grasp_sdk-0.1.5}/grasp_sdk/models/__init__.py +0 -0
  14. {grasp_sdk-0.1.3 → grasp_sdk-0.1.5}/grasp_sdk/services/__init__.py +0 -0
  15. {grasp_sdk-0.1.3 → grasp_sdk-0.1.5}/grasp_sdk/services/browser.py +0 -0
  16. {grasp_sdk-0.1.3 → grasp_sdk-0.1.5}/grasp_sdk/services/sandbox.py +0 -0
  17. {grasp_sdk-0.1.3 → grasp_sdk-0.1.5}/grasp_sdk/utils/__init__.py +0 -0
  18. {grasp_sdk-0.1.3 → grasp_sdk-0.1.5}/grasp_sdk/utils/auth.py +0 -0
  19. {grasp_sdk-0.1.3 → grasp_sdk-0.1.5}/grasp_sdk/utils/config.py +0 -0
  20. {grasp_sdk-0.1.3 → grasp_sdk-0.1.5}/grasp_sdk/utils/logger.py +0 -0
  21. {grasp_sdk-0.1.3 → grasp_sdk-0.1.5}/grasp_sdk.egg-info/dependency_links.txt +0 -0
  22. {grasp_sdk-0.1.3 → grasp_sdk-0.1.5}/grasp_sdk.egg-info/entry_points.txt +0 -0
  23. {grasp_sdk-0.1.3 → grasp_sdk-0.1.5}/grasp_sdk.egg-info/not-zip-safe +0 -0
  24. {grasp_sdk-0.1.3 → grasp_sdk-0.1.5}/grasp_sdk.egg-info/requires.txt +0 -0
  25. {grasp_sdk-0.1.3 → grasp_sdk-0.1.5}/grasp_sdk.egg-info/top_level.txt +0 -0
  26. {grasp_sdk-0.1.3 → grasp_sdk-0.1.5}/py.typed +0 -0
  27. {grasp_sdk-0.1.3 → grasp_sdk-0.1.5}/requirements.txt +0 -0
  28. {grasp_sdk-0.1.3 → grasp_sdk-0.1.5}/setup.cfg +0 -0
  29. {grasp_sdk-0.1.3 → grasp_sdk-0.1.5}/setup.py +0 -0
  30. {grasp_sdk-0.1.3 → grasp_sdk-0.1.5}/test_install.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: grasp_sdk
3
- Version: 0.1.3
3
+ Version: 0.1.5
4
4
  Summary: Python SDK for Grasp E2B - Browser automation and sandbox management
5
5
  Home-page: https://github.com/grasp-team/grasp-e2b
6
6
  Author: Grasp Team
@@ -47,8 +47,14 @@ Dynamic: requires-python
47
47
 
48
48
  # Grasp SDK - Python Implementation
49
49
 
50
+ [![PyPI version](https://badge.fury.io/py/grasp-sdk.svg)](https://badge.fury.io/py/grasp-sdk)
51
+ [![Python 3.8+](https://img.shields.io/badge/python-3.8+-blue.svg)](https://www.python.org/downloads/)
52
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
53
+
50
54
  🐍 Python implementation of Grasp SDK for E2B platform providing secure command execution and browser automation in isolated cloud environments.
51
55
 
56
+ **Current Version: 0.1.4** - [View on PyPI](https://pypi.org/project/grasp-sdk/0.1.4/)
57
+
52
58
  ## 🚀 Features
53
59
 
54
60
  - **Secure Execution**: Run commands and scripts in isolated E2B sandboxes
@@ -61,8 +67,8 @@ Dynamic: requires-python
61
67
  ## 📦 Installation
62
68
 
63
69
  ```bash
64
- # Install from PyPI (when published)
65
- pip install grasp-sdk
70
+ # Install from PyPI
71
+ pip install grasp_sdk
66
72
 
67
73
  # Install from source
68
74
  pip install -e .
@@ -300,6 +306,18 @@ This Python implementation provides the same API surface as the Node.js/TypeScri
300
306
 
301
307
  MIT License - see the [LICENSE](../LICENSE) file for details.
302
308
 
309
+ ## 📋 Release History
310
+
311
+ ### v0.1.4 (2025-01-27)
312
+ - Version synchronization update
313
+ - Package metadata improvements
314
+ - Documentation updates
315
+
316
+ ### v0.1.0 (2025-01-27)
317
+ - Initial release
318
+ - Core functionality implementation
319
+ - Complete API compatibility with Node.js version
320
+
303
321
  ## 🔗 Related
304
322
 
305
323
  - [Node.js/TypeScript Implementation](../src/)
@@ -1,7 +1,13 @@
1
1
  # Grasp SDK - Python Implementation
2
2
 
3
+ [![PyPI version](https://badge.fury.io/py/grasp-sdk.svg)](https://badge.fury.io/py/grasp-sdk)
4
+ [![Python 3.8+](https://img.shields.io/badge/python-3.8+-blue.svg)](https://www.python.org/downloads/)
5
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
6
+
3
7
  🐍 Python implementation of Grasp SDK for E2B platform providing secure command execution and browser automation in isolated cloud environments.
4
8
 
9
+ **Current Version: 0.1.4** - [View on PyPI](https://pypi.org/project/grasp-sdk/0.1.4/)
10
+
5
11
  ## 🚀 Features
6
12
 
7
13
  - **Secure Execution**: Run commands and scripts in isolated E2B sandboxes
@@ -14,8 +20,8 @@
14
20
  ## 📦 Installation
15
21
 
16
22
  ```bash
17
- # Install from PyPI (when published)
18
- pip install grasp-sdk
23
+ # Install from PyPI
24
+ pip install grasp_sdk
19
25
 
20
26
  # Install from source
21
27
  pip install -e .
@@ -253,6 +259,18 @@ This Python implementation provides the same API surface as the Node.js/TypeScri
253
259
 
254
260
  MIT License - see the [LICENSE](../LICENSE) file for details.
255
261
 
262
+ ## 📋 Release History
263
+
264
+ ### v0.1.4 (2025-01-27)
265
+ - Version synchronization update
266
+ - Package metadata improvements
267
+ - Documentation updates
268
+
269
+ ### v0.1.0 (2025-01-27)
270
+ - Initial release
271
+ - Core functionality implementation
272
+ - Complete API compatibility with Node.js version
273
+
256
274
  ## 🔗 Related
257
275
 
258
276
  - [Node.js/TypeScript Implementation](../src/)
@@ -24,7 +24,7 @@ from .models import (
24
24
  SandboxStatus,
25
25
  )
26
26
 
27
- __version__ = "0.1.1"
27
+ __version__ = "0.1.5"
28
28
  __author__ = "Grasp Team"
29
29
  __email__ = "team@grasp.dev"
30
30
 
@@ -45,21 +45,33 @@ class GraspServer:
45
45
  browser_type = sandbox_config.pop('type', 'chromium')
46
46
  headless = sandbox_config.pop('headless', True)
47
47
  adblock = sandbox_config.pop('adblock', False)
48
+ logLevel = sandbox_config.pop('logLevel', '')
49
+ keepAliveMS = sandbox_config.pop('keepAliveMS', 0)
50
+
51
+ # Set default log level
52
+ if not logLevel:
53
+ logLevel = 'debug' if sandbox_config.get('debug', False) else 'info'
48
54
 
49
55
  self.__browser_type = browser_type
50
56
 
51
57
  # Create browser task
52
58
  self.__browser_config = {
53
59
  'headless': headless,
54
- 'envs': {'ADBLOCK': 'true' if adblock else 'false'}
60
+ 'envs': {
61
+ 'ADBLOCK': 'true' if adblock else 'false',
62
+ 'KEEP_ALIVE_MS': str(keepAliveMS),
63
+ }
55
64
  }
56
65
 
57
66
  config = get_config()
58
67
  config['sandbox'].update(sandbox_config)
59
68
  self.config = config
69
+
70
+ logger = config['logger']
71
+ logger['level'] = logLevel
60
72
 
61
73
  # Initialize logger first
62
- init_logger(config['logger'])
74
+ init_logger(logger)
63
75
  self.logger = get_logger().child('GraspE2B')
64
76
 
65
77
  self.browser_service: Optional[BrowserService] = None
@@ -101,6 +101,7 @@ const headless = process.env.HEADLESS !== 'false';
101
101
  const enableAdblock = process.env.ADBLOCK !== 'false';
102
102
  const timeoutMS = process.env.SANBOX_TIMEOUT;
103
103
  const workspace = process.env.WORKSPACE;
104
+ const keepAliveMS = Number(process.env.KEEP_ALIVE_MS) || 0;
104
105
  const args = [];
105
106
 
106
107
  try {
@@ -108,12 +109,37 @@ try {
108
109
 
109
110
  args.push(
110
111
  '--no-sandbox',
112
+ '--disable-setuid-sandbox',
111
113
  '--disable-dev-shm-usage',
112
114
  '--disable-gpu',
113
115
  '--disable-software-rasterizer',
114
116
  '--user-data-dir=/home/user/.browser-context'
115
117
  );
116
118
 
119
+ args.push(
120
+ // 避免缓存积累影响性能
121
+ '--disable-application-cache',
122
+
123
+ // 关闭所有硬件加速特性,防止 GPU 相关崩溃
124
+ '--disable-accelerated-2d-canvas',
125
+ '--disable-accelerated-video-decode',
126
+
127
+ // 禁用后台渲染,减少无关资源消耗
128
+ '--disable-background-timer-throttling',
129
+ '--disable-backgrounding-occluded-windows',
130
+ '--disable-renderer-backgrounding',
131
+
132
+ // 避免过度日志影响性能
133
+ '--disable-logging',
134
+
135
+ // 禁用不必要的多媒体解码
136
+ '--mute-audio',
137
+
138
+ // 避免崩溃时弹窗
139
+ '--no-default-browser-check',
140
+ '--no-first-run',
141
+ );
142
+
117
143
  if(headless) {
118
144
  args.push('--headless=new');
119
145
  }
@@ -187,16 +213,37 @@ try {
187
213
  changeOrigin: true
188
214
  });
189
215
 
216
+ let wsId = null;
217
+
190
218
  // Log WebSocket messages
191
219
  proxy.on('open', () => {
192
220
  console.log('🔌 CDP WebSocket connection established');
193
- logger.info('CDP WebSocket connection established', { sandboxId });
221
+ wsId = Date.now();
222
+ logger.info('CDP WebSocket connection established', { sandboxId, wsId });
194
223
  Sentry.addBreadcrumb({
195
224
  category: 'websocket',
196
225
  message: 'CDP connection established',
197
226
  level: 'info',
198
227
  data: { sandboxId }
199
228
  });
229
+
230
+ const closeId = wsId;
231
+ proxy.once('close', async (req, socket, head) => {
232
+ console.log('🔒 CDP WebSocket connection closed');
233
+ await logger.info('CDP WebSocket connection closed', { sandboxId });
234
+ Sentry.addBreadcrumb({
235
+ category: 'websocket',
236
+ message: 'CDP connection closed',
237
+ level: 'info',
238
+ data: { sandboxId }
239
+ });
240
+ setTimeout(() => {
241
+ if(wsId === closeId) {
242
+ console.log('❌ Force closed...', wsId);
243
+ process.exit(0);
244
+ }
245
+ }, keepAliveMS);
246
+ });
200
247
  });
201
248
 
202
249
  proxy.on('proxyReqWs', (proxyReq, req, socket, options, head) => {
@@ -218,18 +265,6 @@ try {
218
265
  extra: { url: req?.url }
219
266
  });
220
267
  });
221
-
222
- proxy.on('close', async (req, socket, head) => {
223
- console.log('🔒 CDP WebSocket connection closed');
224
- await logger.info('CDP WebSocket connection closed', { sandboxId });
225
- Sentry.addBreadcrumb({
226
- category: 'websocket',
227
- message: 'CDP connection closed',
228
- level: 'info',
229
- data: { sandboxId }
230
- });
231
- process.exit(0);
232
- });
233
268
 
234
269
  const server = http.createServer(async (req, res) => {
235
270
  if (req.url === '/health') {
@@ -6,8 +6,6 @@ import http from 'http';
6
6
  import { Logtail } from '@logtail/node';
7
7
  import * as Sentry from "@sentry/node";
8
8
 
9
- // console.log(`💬 ${JSON.stringify(process.env)}`)
10
-
11
9
  const logtail = new Logtail(process.env.BS_SOURCE_TOKEN, {
12
10
  endpoint: `https://${process.env.BS_INGESTING_HOST}`,
13
11
  });
@@ -104,6 +102,7 @@ const headless = process.env.HEADLESS !== 'false';
104
102
  const enableAdblock = process.env.ADBLOCK !== 'false';
105
103
  const timeoutMS = process.env.SANBOX_TIMEOUT;
106
104
  const workspace = process.env.WORKSPACE;
105
+ const keepAliveMS = Number(process.env.KEEP_ALIVE_MS) || 0;
107
106
  const args = [];
108
107
 
109
108
  try {
@@ -124,6 +123,7 @@ try {
124
123
  '--disable-background-timer-throttling',
125
124
  '--disable-backgrounding-occluded-windows',
126
125
  '--disable-renderer-backgrounding',
126
+ "--disable-software-rasterizer",
127
127
  ...JSON.parse(process.env.BROWSER_ARGS),
128
128
  );
129
129
 
@@ -184,16 +184,37 @@ try {
184
184
  changeOrigin: true
185
185
  });
186
186
 
187
+ let wsId = null;
188
+
187
189
  // 监听 WebSocket 事件
188
190
  proxy.on('open', () => {
189
191
  console.log('🔌 CDP WebSocket connection established');
190
- logger.info('CDP WebSocket connection established', { sandboxId });
192
+ wsId = Date.now();
193
+ logger.info('CDP WebSocket connection established', { sandboxId, wsId });
191
194
  Sentry.addBreadcrumb({
192
195
  category: 'websocket',
193
196
  message: 'CDP connection established',
194
197
  level: 'info',
195
198
  data: { sandboxId }
196
199
  });
200
+
201
+ const closeId = wsId;
202
+ proxy.once('close', async (req, socket, head) => {
203
+ console.log('🔒 CDP WebSocket connection closed');
204
+ await logger.info('CDP WebSocket connection closed', { sandboxId });
205
+ Sentry.addBreadcrumb({
206
+ category: 'websocket',
207
+ message: 'CDP connection closed',
208
+ level: 'info',
209
+ data: { sandboxId }
210
+ });
211
+ setTimeout(() => {
212
+ if(wsId === closeId) {
213
+ console.log('❌ Force closed...', wsId);
214
+ process.exit(0);
215
+ }
216
+ }, keepAliveMS);
217
+ });
197
218
  });
198
219
 
199
220
  proxy.on('proxyReqWs', (proxyReq, req, socket, options, head) => {
@@ -215,18 +236,6 @@ try {
215
236
  extra: { url: req?.url }
216
237
  });
217
238
  });
218
-
219
- proxy.on('close', async (req, socket, head) => {
220
- console.log('🔒 CDP WebSocket connection closed');
221
- await logger.info('CDP WebSocket connection closed', { sandboxId });
222
- Sentry.addBreadcrumb({
223
- category: 'websocket',
224
- message: 'CDP connection closed',
225
- level: 'info',
226
- data: { sandboxId }
227
- });
228
- process.exit(0);
229
- });
230
239
 
231
240
  const server = http.createServer(async (req, res) => {
232
241
  if (req.url === '/health') {
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: grasp_sdk
3
- Version: 0.1.3
3
+ Version: 0.1.5
4
4
  Summary: Python SDK for Grasp E2B - Browser automation and sandbox management
5
5
  Home-page: https://github.com/grasp-team/grasp-e2b
6
6
  Author: Grasp Team
@@ -47,8 +47,14 @@ Dynamic: requires-python
47
47
 
48
48
  # Grasp SDK - Python Implementation
49
49
 
50
+ [![PyPI version](https://badge.fury.io/py/grasp-sdk.svg)](https://badge.fury.io/py/grasp-sdk)
51
+ [![Python 3.8+](https://img.shields.io/badge/python-3.8+-blue.svg)](https://www.python.org/downloads/)
52
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
53
+
50
54
  🐍 Python implementation of Grasp SDK for E2B platform providing secure command execution and browser automation in isolated cloud environments.
51
55
 
56
+ **Current Version: 0.1.4** - [View on PyPI](https://pypi.org/project/grasp-sdk/0.1.4/)
57
+
52
58
  ## 🚀 Features
53
59
 
54
60
  - **Secure Execution**: Run commands and scripts in isolated E2B sandboxes
@@ -61,8 +67,8 @@ Dynamic: requires-python
61
67
  ## 📦 Installation
62
68
 
63
69
  ```bash
64
- # Install from PyPI (when published)
65
- pip install grasp-sdk
70
+ # Install from PyPI
71
+ pip install grasp_sdk
66
72
 
67
73
  # Install from source
68
74
  pip install -e .
@@ -300,6 +306,18 @@ This Python implementation provides the same API surface as the Node.js/TypeScri
300
306
 
301
307
  MIT License - see the [LICENSE](../LICENSE) file for details.
302
308
 
309
+ ## 📋 Release History
310
+
311
+ ### v0.1.4 (2025-01-27)
312
+ - Version synchronization update
313
+ - Package metadata improvements
314
+ - Documentation updates
315
+
316
+ ### v0.1.0 (2025-01-27)
317
+ - Initial release
318
+ - Core functionality implementation
319
+ - Complete API compatibility with Node.js version
320
+
303
321
  ## 🔗 Related
304
322
 
305
323
  - [Node.js/TypeScript Implementation](../src/)
@@ -32,7 +32,6 @@ grasp_sdk.egg-info/top_level.txt
32
32
  grasp_sdk/models/__init__.py
33
33
  grasp_sdk/sandbox/chrome-stable.mjs
34
34
  grasp_sdk/sandbox/chromium.mjs
35
- grasp_sdk/sandbox/jsconfig.json
36
35
  grasp_sdk/services/__init__.py
37
36
  grasp_sdk/services/browser.py
38
37
  grasp_sdk/services/sandbox.py
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "grasp_sdk"
7
- version = "0.1.3"
7
+ version = "0.1.5"
8
8
  authors = [
9
9
  {name = "Grasp Team", email = "team@grasp.com"},
10
10
  ]
@@ -1,22 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "target": "ES2022",
4
- "module": "ESNext",
5
- "moduleResolution": "node",
6
- "allowSyntheticDefaultImports": true,
7
- "esModuleInterop": true,
8
- "allowJs": true,
9
- "checkJs": true,
10
- "strict": false,
11
- "noEmit": true,
12
- "skipLibCheck": true,
13
- "forceConsistentCasingInFileNames": true
14
- },
15
- "include": [
16
- "*.mjs",
17
- "*.js"
18
- ],
19
- "exclude": [
20
- "node_modules"
21
- ]
22
- }
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes