e2b-code-interpreter 2.8.1__tar.gz → 2.9.1__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,8 +1,7 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.3
2
2
  Name: e2b-code-interpreter
3
- Version: 2.8.1
3
+ Version: 2.9.1
4
4
  Summary: E2B Code Interpreter - Stateful code execution
5
- Home-page: https://e2b.dev/
6
5
  License: MIT
7
6
  Author: e2b
8
7
  Author-email: hello@e2b.dev
@@ -14,9 +13,10 @@ Classifier: Programming Language :: Python :: 3.11
14
13
  Classifier: Programming Language :: Python :: 3.12
15
14
  Classifier: Programming Language :: Python :: 3.13
16
15
  Requires-Dist: attrs (>=21.3.0)
17
- Requires-Dist: e2b (>=2.26.0,<3.0.0)
16
+ Requires-Dist: e2b (>=2.39.1,<3.0.0)
18
17
  Requires-Dist: httpx (>=0.20.0,<1.0.0)
19
18
  Project-URL: Bug Tracker, https://github.com/e2b-dev/code-interpreter/issues
19
+ Project-URL: Homepage, https://e2b.dev/
20
20
  Project-URL: Repository, https://github.com/e2b-dev/code-interpreter/tree/main/python
21
21
  Description-Content-Type: text/markdown
22
22
 
@@ -61,6 +61,11 @@ 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 = self.connection_config._sandbox_url
67
+ if sandbox_url:
68
+ return sandbox_url
64
69
  return f"{'http' if self.connection_config.debug else 'https'}://{self.get_host(JUPYTER_PORT)}"
65
70
 
66
71
  @property
@@ -196,6 +201,8 @@ class AsyncSandbox(BaseAsyncSandbox):
196
201
  try:
197
202
  headers = {
198
203
  "Content-Type": "application/json",
204
+ "E2b-Sandbox-Id": self.sandbox_id,
205
+ "E2b-Sandbox-Port": str(JUPYTER_PORT),
199
206
  }
200
207
  if self._envd_access_token:
201
208
  headers["X-Access-Token"] = self._envd_access_token
@@ -212,7 +219,22 @@ class AsyncSandbox(BaseAsyncSandbox):
212
219
  "env_vars": envs,
213
220
  },
214
221
  headers=headers,
215
- timeout=(request_timeout, timeout, request_timeout, request_timeout),
222
+ # `timeout` bounds the execution, `request_timeout` only the
223
+ # connect. Every non-connect phase must carry `timeout`: the
224
+ # SDK's pyqwest-backed transport collapses the per-phase
225
+ # timeouts into a single whole-request deadline and takes the
226
+ # longest of them, so leaving `request_timeout` on the write
227
+ # and pool phases would raise the floor to
228
+ # `max(timeout, request_timeout)` and silently ignore any
229
+ # `timeout` shorter than it. This matches the JS SDK, which
230
+ # aborts the execution on a `timeout`-long timer.
231
+ # `timeout=0` disables the deadline entirely; the transport
232
+ # still bounds connect on its own.
233
+ timeout=(
234
+ httpx.Timeout(timeout, connect=request_timeout)
235
+ if timeout is not None
236
+ else httpx.Timeout(None)
237
+ ),
216
238
  ) as response:
217
239
  err = await aextract_exception(response)
218
240
  if err:
@@ -265,6 +287,8 @@ class AsyncSandbox(BaseAsyncSandbox):
265
287
  try:
266
288
  headers = {
267
289
  "Content-Type": "application/json",
290
+ "E2b-Sandbox-Id": self.sandbox_id,
291
+ "E2b-Sandbox-Port": str(JUPYTER_PORT),
268
292
  }
269
293
  if self.traffic_access_token:
270
294
  headers["E2B-Traffic-Access-Token"] = self.traffic_access_token
@@ -304,6 +328,8 @@ class AsyncSandbox(BaseAsyncSandbox):
304
328
  try:
305
329
  headers = {
306
330
  "Content-Type": "application/json",
331
+ "E2b-Sandbox-Id": self.sandbox_id,
332
+ "E2b-Sandbox-Port": str(JUPYTER_PORT),
307
333
  }
308
334
  if self.traffic_access_token:
309
335
  headers["E2B-Traffic-Access-Token"] = self.traffic_access_token
@@ -332,6 +358,8 @@ class AsyncSandbox(BaseAsyncSandbox):
332
358
  try:
333
359
  headers = {
334
360
  "Content-Type": "application/json",
361
+ "E2b-Sandbox-Id": self.sandbox_id,
362
+ "E2b-Sandbox-Port": str(JUPYTER_PORT),
335
363
  }
336
364
  if self.traffic_access_token:
337
365
  headers["E2B-Traffic-Access-Token"] = self.traffic_access_token
@@ -369,6 +397,8 @@ class AsyncSandbox(BaseAsyncSandbox):
369
397
  try:
370
398
  headers = {
371
399
  "Content-Type": "application/json",
400
+ "E2b-Sandbox-Id": self.sandbox_id,
401
+ "E2b-Sandbox-Port": str(JUPYTER_PORT),
372
402
  }
373
403
  if self.traffic_access_token:
374
404
  headers["E2B-Traffic-Access-Token"] = self.traffic_access_token
@@ -58,6 +58,11 @@ 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 = self.connection_config._sandbox_url
64
+ if sandbox_url:
65
+ return sandbox_url
61
66
  return f"{'http' if self.connection_config.debug else 'https'}://{self.get_host(JUPYTER_PORT)}"
62
67
 
63
68
  @property
@@ -189,7 +194,11 @@ class Sandbox(BaseSandbox):
189
194
  context_id = context.id if context else None
190
195
 
191
196
  try:
192
- headers: Dict[str, str] = {"Content-Type": "application/json"}
197
+ headers: Dict[str, str] = {
198
+ "Content-Type": "application/json",
199
+ "E2b-Sandbox-Id": self.sandbox_id,
200
+ "E2b-Sandbox-Port": str(JUPYTER_PORT),
201
+ }
193
202
  if self._envd_access_token:
194
203
  headers["X-Access-Token"] = self._envd_access_token
195
204
  if self.traffic_access_token:
@@ -205,7 +214,22 @@ class Sandbox(BaseSandbox):
205
214
  "env_vars": envs,
206
215
  },
207
216
  headers=headers,
208
- timeout=(request_timeout, timeout, request_timeout, request_timeout),
217
+ # `timeout` bounds the execution, `request_timeout` only the
218
+ # connect. Every non-connect phase must carry `timeout`: the
219
+ # SDK's pyqwest-backed transport collapses the per-phase
220
+ # timeouts into a single whole-request deadline and takes the
221
+ # longest of them, so leaving `request_timeout` on the write
222
+ # and pool phases would raise the floor to
223
+ # `max(timeout, request_timeout)` and silently ignore any
224
+ # `timeout` shorter than it. This matches the JS SDK, which
225
+ # aborts the execution on a `timeout`-long timer.
226
+ # `timeout=0` disables the deadline entirely; the transport
227
+ # still bounds connect on its own.
228
+ timeout=(
229
+ httpx.Timeout(timeout, connect=request_timeout)
230
+ if timeout is not None
231
+ else httpx.Timeout(None)
232
+ ),
209
233
  ) as response:
210
234
  err = extract_exception(response)
211
235
  if err:
@@ -256,9 +280,11 @@ class Sandbox(BaseSandbox):
256
280
  data["cwd"] = cwd
257
281
 
258
282
  try:
259
- headers: Dict[str, str] = {"Content-Type": "application/json"}
260
- if self._envd_access_token:
261
- headers["X-Access-Token"] = self._envd_access_token
283
+ headers: Dict[str, str] = {
284
+ "Content-Type": "application/json",
285
+ "E2b-Sandbox-Id": self.sandbox_id,
286
+ "E2b-Sandbox-Port": str(JUPYTER_PORT),
287
+ }
262
288
  if self.traffic_access_token:
263
289
  headers["E2B-Traffic-Access-Token"] = self.traffic_access_token
264
290
 
@@ -295,9 +321,11 @@ class Sandbox(BaseSandbox):
295
321
  context_id = context.id if isinstance(context, Context) else context
296
322
 
297
323
  try:
298
- headers: Dict[str, str] = {"Content-Type": "application/json"}
299
- if self._envd_access_token:
300
- headers["X-Access-Token"] = self._envd_access_token
324
+ headers: Dict[str, str] = {
325
+ "Content-Type": "application/json",
326
+ "E2b-Sandbox-Id": self.sandbox_id,
327
+ "E2b-Sandbox-Port": str(JUPYTER_PORT),
328
+ }
301
329
  if self.traffic_access_token:
302
330
  headers["E2B-Traffic-Access-Token"] = self.traffic_access_token
303
331
 
@@ -323,9 +351,11 @@ class Sandbox(BaseSandbox):
323
351
  :return: List of contexts.
324
352
  """
325
353
  try:
326
- headers: Dict[str, str] = {"Content-Type": "application/json"}
327
- if self._envd_access_token:
328
- headers["X-Access-Token"] = self._envd_access_token
354
+ headers: Dict[str, str] = {
355
+ "Content-Type": "application/json",
356
+ "E2b-Sandbox-Id": self.sandbox_id,
357
+ "E2b-Sandbox-Port": str(JUPYTER_PORT),
358
+ }
329
359
  if self.traffic_access_token:
330
360
  headers["E2B-Traffic-Access-Token"] = self.traffic_access_token
331
361
 
@@ -361,9 +391,11 @@ class Sandbox(BaseSandbox):
361
391
  context_id = context.id if isinstance(context, Context) else context
362
392
 
363
393
  try:
364
- headers: Dict[str, str] = {"Content-Type": "application/json"}
365
- if self._envd_access_token:
366
- headers["X-Access-Token"] = self._envd_access_token
394
+ headers: Dict[str, str] = {
395
+ "Content-Type": "application/json",
396
+ "E2b-Sandbox-Id": self.sandbox_id,
397
+ "E2b-Sandbox-Port": str(JUPYTER_PORT),
398
+ }
367
399
  if self.traffic_access_token:
368
400
  headers["E2B-Traffic-Access-Token"] = self.traffic_access_token
369
401
 
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "e2b-code-interpreter"
3
- version = "2.8.1"
3
+ version = "2.9.1"
4
4
  description = "E2B Code Interpreter - Stateful code execution"
5
5
  authors = ["e2b <hello@e2b.dev>"]
6
6
  license = "MIT"
@@ -14,7 +14,7 @@ python = "^3.10"
14
14
 
15
15
  httpx = ">=0.20.0, <1.0.0"
16
16
  attrs = ">=21.3.0"
17
- e2b = "^2.26.0"
17
+ e2b = "^2.39.1"
18
18
 
19
19
  [tool.poetry.group.dev.dependencies]
20
20
  pytest = "^9.0.3"