e2b-code-interpreter 2.10.1__tar.gz → 2.10.4__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.
@@ -1,13 +1,13 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: e2b-code-interpreter
3
- Version: 2.10.1
3
+ Version: 2.10.4
4
4
  Summary: E2B Code Interpreter - Stateful code execution
5
5
  Author: e2b
6
6
  Author-email: e2b <hello@e2b.dev>
7
7
  License-Expression: MIT
8
8
  Requires-Dist: httpx>=0.20.0,<1.0.0
9
9
  Requires-Dist: attrs>=21.3.0
10
- Requires-Dist: e2b>=2.52.0,<3.0.0
10
+ Requires-Dist: e2b>=2.55.0,<3.0.0
11
11
  Requires-Python: >=3.10
12
12
  Project-URL: Homepage, https://e2b.dev/?utm_source=pypi&utm_medium=referral&utm_campaign=package_homepage&utm_content=e2b-code-interpreter
13
13
  Project-URL: Repository, https://github.com/e2b-dev/e2b/tree/main/packages/code-interpreter-python
@@ -1,7 +1,7 @@
1
1
  import logging
2
2
  import httpx
3
3
 
4
- from typing import cast, Optional, Dict, overload, Union, List
4
+ from typing import Optional, Dict, overload, Union, List
5
5
  from httpx import AsyncClient
6
6
 
7
7
  from e2b import (
@@ -61,24 +61,9 @@ class AsyncSandbox(BaseAsyncSandbox):
61
61
 
62
62
  @property
63
63
  def _jupyter_url(self) -> str:
64
- # Honors the `sandbox_url` option and the `E2B_SANDBOX_URL` environment
65
- # variable, same as the base SDK does for envd requests.
66
- sandbox_url = cast(Optional[str], self.connection_config._sandbox_url)
67
- if sandbox_url:
68
- return sandbox_url
69
- return f"{'http' if self.connection_config.debug else 'https'}://{self.get_host(JUPYTER_PORT)}"
70
-
71
- def _jupyter_request_url(self, path: str) -> str:
72
- url = f"{self._jupyter_url}{path}"
73
- source = getattr(self.connection_config, "request_source", None)
74
- if not source:
75
- return url
76
- separator = "&" if "?" in url else "?"
77
- return f"{url}{separator}source={source}"
78
-
79
- @property
80
- def _include_diagnostics(self) -> bool:
81
- return getattr(self.connection_config, "request_source", None) == "ci"
64
+ return self.connection_config.get_sandbox_url(
65
+ self.sandbox_id, self.sandbox_domain, port=JUPYTER_PORT
66
+ )
82
67
 
83
68
  @property
84
69
  def _client(self) -> AsyncClient:
@@ -223,7 +208,7 @@ class AsyncSandbox(BaseAsyncSandbox):
223
208
 
224
209
  async with self._client.stream(
225
210
  "POST",
226
- self._jupyter_request_url("/execute"),
211
+ f"{self._jupyter_url}/execute",
227
212
  json={
228
213
  "code": code,
229
214
  "context_id": context_id,
@@ -248,7 +233,7 @@ class AsyncSandbox(BaseAsyncSandbox):
248
233
  else httpx.Timeout(None)
249
234
  ),
250
235
  ) as response:
251
- err = await aextract_exception(response, self._include_diagnostics)
236
+ err = await aextract_exception(response)
252
237
  if err:
253
238
  raise err
254
239
 
@@ -306,13 +291,13 @@ class AsyncSandbox(BaseAsyncSandbox):
306
291
  headers["E2B-Traffic-Access-Token"] = self.traffic_access_token
307
292
 
308
293
  response = await self._client.post(
309
- self._jupyter_request_url("/contexts"),
294
+ f"{self._jupyter_url}/contexts",
310
295
  headers=headers,
311
296
  json=data,
312
297
  timeout=request_timeout or self.connection_config.request_timeout,
313
298
  )
314
299
 
315
- err = await aextract_exception(response, self._include_diagnostics)
300
+ err = await aextract_exception(response)
316
301
  if err:
317
302
  raise err
318
303
 
@@ -347,12 +332,12 @@ class AsyncSandbox(BaseAsyncSandbox):
347
332
  headers["E2B-Traffic-Access-Token"] = self.traffic_access_token
348
333
 
349
334
  response = await self._client.delete(
350
- self._jupyter_request_url(f"/contexts/{context_id}"),
335
+ f"{self._jupyter_url}/contexts/{context_id}",
351
336
  headers=headers,
352
337
  timeout=self.connection_config.request_timeout,
353
338
  )
354
339
 
355
- err = await aextract_exception(response, self._include_diagnostics)
340
+ err = await aextract_exception(response)
356
341
  if err:
357
342
  raise err
358
343
  except httpx.TimeoutException:
@@ -377,12 +362,12 @@ class AsyncSandbox(BaseAsyncSandbox):
377
362
  headers["E2B-Traffic-Access-Token"] = self.traffic_access_token
378
363
 
379
364
  response = await self._client.get(
380
- self._jupyter_request_url("/contexts"),
365
+ f"{self._jupyter_url}/contexts",
381
366
  headers=headers,
382
367
  timeout=self.connection_config.request_timeout,
383
368
  )
384
369
 
385
- err = await aextract_exception(response, self._include_diagnostics)
370
+ err = await aextract_exception(response)
386
371
  if err:
387
372
  raise err
388
373
 
@@ -416,12 +401,12 @@ class AsyncSandbox(BaseAsyncSandbox):
416
401
  headers["E2B-Traffic-Access-Token"] = self.traffic_access_token
417
402
 
418
403
  response = await self._client.post(
419
- self._jupyter_request_url(f"/contexts/{context_id}/restart"),
404
+ f"{self._jupyter_url}/contexts/{context_id}/restart",
420
405
  headers=headers,
421
406
  timeout=self.connection_config.request_timeout,
422
407
  )
423
408
 
424
- err = await aextract_exception(response, self._include_diagnostics)
409
+ err = await aextract_exception(response)
425
410
  if err:
426
411
  raise err
427
412
  except httpx.TimeoutException:
@@ -1,7 +1,7 @@
1
1
  import logging
2
2
  import httpx
3
3
 
4
- from typing import cast, Optional, Dict, overload, Union, List
4
+ from typing import Optional, Dict, overload, Union, List
5
5
  from httpx import Client
6
6
  from e2b import Sandbox as BaseSandbox, InvalidArgumentException
7
7
  from e2b.api.client_sync import get_transport
@@ -58,24 +58,9 @@ class Sandbox(BaseSandbox):
58
58
 
59
59
  @property
60
60
  def _jupyter_url(self) -> str:
61
- # Honors the `sandbox_url` option and the `E2B_SANDBOX_URL` environment
62
- # variable, same as the base SDK does for envd requests.
63
- sandbox_url = cast(Optional[str], self.connection_config._sandbox_url)
64
- if sandbox_url:
65
- return sandbox_url
66
- return f"{'http' if self.connection_config.debug else 'https'}://{self.get_host(JUPYTER_PORT)}"
67
-
68
- def _jupyter_request_url(self, path: str) -> str:
69
- url = f"{self._jupyter_url}{path}"
70
- source = getattr(self.connection_config, "request_source", None)
71
- if not source:
72
- return url
73
- separator = "&" if "?" in url else "?"
74
- return f"{url}{separator}source={source}"
75
-
76
- @property
77
- def _include_diagnostics(self) -> bool:
78
- return getattr(self.connection_config, "request_source", None) == "ci"
61
+ return self.connection_config.get_sandbox_url(
62
+ self.sandbox_id, self.sandbox_domain, port=JUPYTER_PORT
63
+ )
79
64
 
80
65
  @property
81
66
  def _client(self) -> Client:
@@ -220,7 +205,7 @@ class Sandbox(BaseSandbox):
220
205
 
221
206
  with self._client.stream(
222
207
  "POST",
223
- self._jupyter_request_url("/execute"),
208
+ f"{self._jupyter_url}/execute",
224
209
  json={
225
210
  "code": code,
226
211
  "context_id": context_id,
@@ -245,7 +230,7 @@ class Sandbox(BaseSandbox):
245
230
  else httpx.Timeout(None)
246
231
  ),
247
232
  ) as response:
248
- err = extract_exception(response, self._include_diagnostics)
233
+ err = extract_exception(response)
249
234
  if err:
250
235
  raise err
251
236
 
@@ -303,13 +288,13 @@ class Sandbox(BaseSandbox):
303
288
  headers["E2B-Traffic-Access-Token"] = self.traffic_access_token
304
289
 
305
290
  response = self._client.post(
306
- self._jupyter_request_url("/contexts"),
291
+ f"{self._jupyter_url}/contexts",
307
292
  json=data,
308
293
  headers=headers,
309
294
  timeout=request_timeout or self.connection_config.request_timeout,
310
295
  )
311
296
 
312
- err = extract_exception(response, self._include_diagnostics)
297
+ err = extract_exception(response)
313
298
  if err:
314
299
  raise err
315
300
 
@@ -344,12 +329,12 @@ class Sandbox(BaseSandbox):
344
329
  headers["E2B-Traffic-Access-Token"] = self.traffic_access_token
345
330
 
346
331
  response = self._client.delete(
347
- self._jupyter_request_url(f"/contexts/{context_id}"),
332
+ f"{self._jupyter_url}/contexts/{context_id}",
348
333
  headers=headers,
349
334
  timeout=self.connection_config.request_timeout,
350
335
  )
351
336
 
352
- err = extract_exception(response, self._include_diagnostics)
337
+ err = extract_exception(response)
353
338
  if err:
354
339
  raise err
355
340
  except httpx.TimeoutException:
@@ -374,12 +359,12 @@ class Sandbox(BaseSandbox):
374
359
  headers["E2B-Traffic-Access-Token"] = self.traffic_access_token
375
360
 
376
361
  response = self._client.get(
377
- self._jupyter_request_url("/contexts"),
362
+ f"{self._jupyter_url}/contexts",
378
363
  headers=headers,
379
364
  timeout=self.connection_config.request_timeout,
380
365
  )
381
366
 
382
- err = extract_exception(response, self._include_diagnostics)
367
+ err = extract_exception(response)
383
368
  if err:
384
369
  raise err
385
370
 
@@ -414,12 +399,12 @@ class Sandbox(BaseSandbox):
414
399
  headers["E2B-Traffic-Access-Token"] = self.traffic_access_token
415
400
 
416
401
  response = self._client.post(
417
- self._jupyter_request_url(f"/contexts/{context_id}/restart"),
402
+ f"{self._jupyter_url}/contexts/{context_id}/restart",
418
403
  headers=headers,
419
404
  timeout=self.connection_config.request_timeout,
420
405
  )
421
406
 
422
- err = extract_exception(response, self._include_diagnostics)
407
+ err = extract_exception(response)
423
408
  if err:
424
409
  raise err
425
410
  except httpx.TimeoutException:
@@ -400,40 +400,36 @@ class Execution:
400
400
  return json.dumps(data)
401
401
 
402
402
 
403
- async def aextract_exception(res: Response, include_diagnostics: bool = False):
403
+ async def aextract_exception(res: Response):
404
404
  if res.is_success:
405
405
  return None
406
406
 
407
407
  await res.aread()
408
- return extract_exception(res, include_diagnostics)
408
+ return extract_exception(res)
409
409
 
410
410
 
411
- def extract_exception(res: Response, include_diagnostics: bool = False):
411
+ def extract_exception(res: Response):
412
412
  if res.is_success:
413
413
  return None
414
414
 
415
415
  res.read()
416
- return format_exception(res, include_diagnostics)
416
+ return format_exception(res)
417
417
 
418
418
 
419
- def format_exception(res: Response, include_diagnostics: bool = False):
419
+ def format_exception(res: Response):
420
420
  if res.is_success:
421
421
  return None
422
422
 
423
- body = res.text
424
- trace_id = res.headers.get("X-E2B-Trace-ID") if include_diagnostics else None
425
- trace_suffix = f" (trace_id={trace_id})" if trace_id else ""
426
-
427
423
  if res.status_code == 404:
428
- return NotFoundException(f"{body}{trace_suffix}")
424
+ return NotFoundException(res.text)
429
425
  elif res.status_code == 502:
430
426
  return TimeoutException(
431
- f"{body}: This error is likely due to sandbox timeout. You can modify the sandbox timeout by passing 'timeout' when starting the sandbox or calling '.set_timeout' on the sandbox with the desired timeout.{trace_suffix}"
427
+ f"{res.text}: This error is likely due to sandbox timeout. You can modify the sandbox timeout by passing 'timeout' when starting the sandbox or calling '.set_timeout' on the sandbox with the desired timeout."
432
428
  )
433
429
  else:
434
- body_separator = "" if trace_suffix and not body else " "
430
+ body = res.text.strip()
435
431
  return SandboxException(
436
- f"{res.status_code}:{body_separator}{body}{trace_suffix}"
432
+ f"{res.status_code} {res.reason_phrase}{f': {body}' if body else ''}"
437
433
  )
438
434
 
439
435
 
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "e2b-code-interpreter"
3
- version = "2.10.1"
3
+ version = "2.10.4"
4
4
  description = "E2B Code Interpreter - Stateful code execution"
5
5
  authors = [{ name = "e2b", email = "hello@e2b.dev" }]
6
6
  license = "MIT"
@@ -9,7 +9,7 @@ requires-python = ">=3.10"
9
9
  dependencies = [
10
10
  "httpx>=0.20.0,<1.0.0",
11
11
  "attrs>=21.3.0",
12
- "e2b>=2.52.0,<3.0.0",
12
+ "e2b>=2.55.0,<3.0.0",
13
13
  ]
14
14
 
15
15
  [project.urls]