e2b-code-interpreter 2.10.0__tar.gz → 2.10.3__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.0
3
+ Version: 2.10.3
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.44.0,<3.0.0
10
+ Requires-Dist: e2b>=2.53.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
@@ -68,24 +68,12 @@ class AsyncSandbox(BaseAsyncSandbox):
68
68
  return sandbox_url
69
69
  return f"{'http' if self.connection_config.debug else 'https'}://{self.get_host(JUPYTER_PORT)}"
70
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"
82
-
83
71
  @property
84
72
  def _client(self) -> AsyncClient:
85
73
  # TODO: Remove later
86
74
  # Use a dedicated HTTP/1.1 transport for Jupyter requests.
87
75
  #
88
- # The base SDK's shared transport now defaults to http2=True. With
76
+ # The base SDK's shared transport now defaults to HTTP/2. With
89
77
  # HTTP/2, multiple requests are multiplexed over a single TCP
90
78
  # connection, so when a client cancels a request (e.g. the caller
91
79
  # disconnects from the streaming `/execute` endpoint) the server
@@ -98,7 +86,7 @@ class AsyncSandbox(BaseAsyncSandbox):
98
86
  # cancelled reliably. The helper also caches the transport
99
87
  # per-event-loop for async.
100
88
  return AsyncClient(
101
- transport=get_transport(self.connection_config, http2=False),
89
+ transport=get_transport(self.connection_config, http_version="1.1"),
102
90
  )
103
91
 
104
92
  async def _handle_connection_error(self, err: Exception) -> None:
@@ -223,7 +211,7 @@ class AsyncSandbox(BaseAsyncSandbox):
223
211
 
224
212
  async with self._client.stream(
225
213
  "POST",
226
- self._jupyter_request_url("/execute"),
214
+ f"{self._jupyter_url}/execute",
227
215
  json={
228
216
  "code": code,
229
217
  "context_id": context_id,
@@ -248,7 +236,7 @@ class AsyncSandbox(BaseAsyncSandbox):
248
236
  else httpx.Timeout(None)
249
237
  ),
250
238
  ) as response:
251
- err = await aextract_exception(response, self._include_diagnostics)
239
+ err = await aextract_exception(response)
252
240
  if err:
253
241
  raise err
254
242
 
@@ -306,13 +294,13 @@ class AsyncSandbox(BaseAsyncSandbox):
306
294
  headers["E2B-Traffic-Access-Token"] = self.traffic_access_token
307
295
 
308
296
  response = await self._client.post(
309
- self._jupyter_request_url("/contexts"),
297
+ f"{self._jupyter_url}/contexts",
310
298
  headers=headers,
311
299
  json=data,
312
300
  timeout=request_timeout or self.connection_config.request_timeout,
313
301
  )
314
302
 
315
- err = await aextract_exception(response, self._include_diagnostics)
303
+ err = await aextract_exception(response)
316
304
  if err:
317
305
  raise err
318
306
 
@@ -347,12 +335,12 @@ class AsyncSandbox(BaseAsyncSandbox):
347
335
  headers["E2B-Traffic-Access-Token"] = self.traffic_access_token
348
336
 
349
337
  response = await self._client.delete(
350
- self._jupyter_request_url(f"/contexts/{context_id}"),
338
+ f"{self._jupyter_url}/contexts/{context_id}",
351
339
  headers=headers,
352
340
  timeout=self.connection_config.request_timeout,
353
341
  )
354
342
 
355
- err = await aextract_exception(response, self._include_diagnostics)
343
+ err = await aextract_exception(response)
356
344
  if err:
357
345
  raise err
358
346
  except httpx.TimeoutException:
@@ -377,12 +365,12 @@ class AsyncSandbox(BaseAsyncSandbox):
377
365
  headers["E2B-Traffic-Access-Token"] = self.traffic_access_token
378
366
 
379
367
  response = await self._client.get(
380
- self._jupyter_request_url("/contexts"),
368
+ f"{self._jupyter_url}/contexts",
381
369
  headers=headers,
382
370
  timeout=self.connection_config.request_timeout,
383
371
  )
384
372
 
385
- err = await aextract_exception(response, self._include_diagnostics)
373
+ err = await aextract_exception(response)
386
374
  if err:
387
375
  raise err
388
376
 
@@ -416,12 +404,12 @@ class AsyncSandbox(BaseAsyncSandbox):
416
404
  headers["E2B-Traffic-Access-Token"] = self.traffic_access_token
417
405
 
418
406
  response = await self._client.post(
419
- self._jupyter_request_url(f"/contexts/{context_id}/restart"),
407
+ f"{self._jupyter_url}/contexts/{context_id}/restart",
420
408
  headers=headers,
421
409
  timeout=self.connection_config.request_timeout,
422
410
  )
423
411
 
424
- err = await aextract_exception(response, self._include_diagnostics)
412
+ err = await aextract_exception(response)
425
413
  if err:
426
414
  raise err
427
415
  except httpx.TimeoutException:
@@ -65,24 +65,12 @@ class Sandbox(BaseSandbox):
65
65
  return sandbox_url
66
66
  return f"{'http' if self.connection_config.debug else 'https'}://{self.get_host(JUPYTER_PORT)}"
67
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"
79
-
80
68
  @property
81
69
  def _client(self) -> Client:
82
70
  # TODO: Remove later
83
71
  # Use a dedicated HTTP/1.1 transport for Jupyter requests.
84
72
  #
85
- # The base SDK's shared transport now defaults to http2=True. With
73
+ # The base SDK's shared transport now defaults to HTTP/2. With
86
74
  # HTTP/2, multiple requests are multiplexed over a single TCP
87
75
  # connection, so when a client cancels a request (e.g. the caller
88
76
  # disconnects from the streaming `/execute` endpoint) the server
@@ -93,7 +81,9 @@ class Sandbox(BaseSandbox):
93
81
  # connection and request, so client disconnects propagate to the
94
82
  # server as a TCP close and long-running executions can be
95
83
  # cancelled reliably.
96
- return Client(transport=get_transport(self.connection_config, http2=False))
84
+ return Client(
85
+ transport=get_transport(self.connection_config, http_version="1.1")
86
+ )
97
87
 
98
88
  def _handle_connection_error(self, err: Exception) -> None:
99
89
  """
@@ -218,7 +208,7 @@ class Sandbox(BaseSandbox):
218
208
 
219
209
  with self._client.stream(
220
210
  "POST",
221
- self._jupyter_request_url("/execute"),
211
+ f"{self._jupyter_url}/execute",
222
212
  json={
223
213
  "code": code,
224
214
  "context_id": context_id,
@@ -243,7 +233,7 @@ class Sandbox(BaseSandbox):
243
233
  else httpx.Timeout(None)
244
234
  ),
245
235
  ) as response:
246
- err = extract_exception(response, self._include_diagnostics)
236
+ err = extract_exception(response)
247
237
  if err:
248
238
  raise err
249
239
 
@@ -301,13 +291,13 @@ class Sandbox(BaseSandbox):
301
291
  headers["E2B-Traffic-Access-Token"] = self.traffic_access_token
302
292
 
303
293
  response = self._client.post(
304
- self._jupyter_request_url("/contexts"),
294
+ f"{self._jupyter_url}/contexts",
305
295
  json=data,
306
296
  headers=headers,
307
297
  timeout=request_timeout or self.connection_config.request_timeout,
308
298
  )
309
299
 
310
- err = extract_exception(response, self._include_diagnostics)
300
+ err = extract_exception(response)
311
301
  if err:
312
302
  raise err
313
303
 
@@ -342,12 +332,12 @@ class Sandbox(BaseSandbox):
342
332
  headers["E2B-Traffic-Access-Token"] = self.traffic_access_token
343
333
 
344
334
  response = self._client.delete(
345
- self._jupyter_request_url(f"/contexts/{context_id}"),
335
+ f"{self._jupyter_url}/contexts/{context_id}",
346
336
  headers=headers,
347
337
  timeout=self.connection_config.request_timeout,
348
338
  )
349
339
 
350
- err = extract_exception(response, self._include_diagnostics)
340
+ err = extract_exception(response)
351
341
  if err:
352
342
  raise err
353
343
  except httpx.TimeoutException:
@@ -372,12 +362,12 @@ class Sandbox(BaseSandbox):
372
362
  headers["E2B-Traffic-Access-Token"] = self.traffic_access_token
373
363
 
374
364
  response = self._client.get(
375
- self._jupyter_request_url("/contexts"),
365
+ f"{self._jupyter_url}/contexts",
376
366
  headers=headers,
377
367
  timeout=self.connection_config.request_timeout,
378
368
  )
379
369
 
380
- err = extract_exception(response, self._include_diagnostics)
370
+ err = extract_exception(response)
381
371
  if err:
382
372
  raise err
383
373
 
@@ -412,12 +402,12 @@ class Sandbox(BaseSandbox):
412
402
  headers["E2B-Traffic-Access-Token"] = self.traffic_access_token
413
403
 
414
404
  response = self._client.post(
415
- self._jupyter_request_url(f"/contexts/{context_id}/restart"),
405
+ f"{self._jupyter_url}/contexts/{context_id}/restart",
416
406
  headers=headers,
417
407
  timeout=self.connection_config.request_timeout,
418
408
  )
419
409
 
420
- err = extract_exception(response, self._include_diagnostics)
410
+ err = extract_exception(response)
421
411
  if err:
422
412
  raise err
423
413
  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.0"
3
+ version = "2.10.3"
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.44.0,<3.0.0",
12
+ "e2b>=2.53.0,<3.0.0",
13
13
  ]
14
14
 
15
15
  [project.urls]