e2b-code-interpreter 0.0.4__tar.gz → 0.0.6__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,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: e2b-code-interpreter
3
- Version: 0.0.4
3
+ Version: 0.0.6
4
4
  Summary: E2B Code Interpreter - Stateful code execution
5
5
  Home-page: https://e2b.dev/
6
6
  License: Apache-2.0
@@ -52,13 +52,13 @@ class CodeInterpreter(Sandbox):
52
52
 
53
53
 
54
54
  class JupyterExtension:
55
- _default_kernel_id: Optional[str] = None
56
- _connected_kernels: Dict[str, Future[JupyterKernelWebSocket]] = {}
57
55
 
58
56
  def __init__(self, sandbox: CodeInterpreter, timeout: Optional[float] = TIMEOUT):
59
57
  self._sandbox = sandbox
60
58
  self._kernel_id_set = Future()
61
59
  self._start_connecting_to_default_kernel(timeout=timeout)
60
+ self._connected_kernels: Dict[str, Future[JupyterKernelWebSocket]] = {}
61
+ self._default_kernel_id: Optional[str] = None
62
62
 
63
63
  def exec_cell(
64
64
  self,
@@ -43,30 +43,29 @@ class CellExecution:
43
43
  self.on_result = on_result
44
44
 
45
45
 
46
- class JupyterKernelWebSocket(BaseModel):
47
- model_config = ConfigDict(arbitrary_types_allowed=True)
46
+ class JupyterKernelWebSocket:
48
47
 
49
- url: str
50
-
51
- _cells: Dict[str, CellExecution] = {}
52
- _waiting_for_replies: Dict[str, DeferredFuture] = PrivateAttr(default_factory=dict)
53
- _queue_in: Queue = PrivateAttr(default_factory=Queue)
54
- _queue_out: Queue = PrivateAttr(default_factory=Queue)
55
- _process_cleanup: List[Callable[[], Any]] = PrivateAttr(default_factory=list)
56
- _closed: bool = PrivateAttr(default=False)
48
+ def __init__(self, url: str):
49
+ self.url = url
50
+ self._cells: Dict[str, CellExecution] = {}
51
+ self._waiting_for_replies: Dict[str, DeferredFuture] = {}
52
+ self._queue_in = Queue()
53
+ self._queue_out = Queue()
54
+ self._stopped = threading.Event()
57
55
 
58
56
  def process_messages(self):
59
- while True:
60
- data = self._queue_out.get()
57
+ while not self._stopped.is_set():
58
+ if self._queue_out.empty():
59
+ time.sleep(0.01)
60
+ continue
61
61
 
62
+ data = self._queue_out.get()
62
63
  logger.debug(f"WebSocket received message: {data}".strip())
63
64
  self._receive_message(json.loads(data))
64
65
  self._queue_out.task_done()
65
66
 
66
67
  def connect(self, timeout: float = TIMEOUT):
67
68
  started = threading.Event()
68
- stopped = threading.Event()
69
- self._process_cleanup.append(stopped.set)
70
69
 
71
70
  threading.Thread(
72
71
  target=self.process_messages, daemon=True, name="e2b-process-messages"
@@ -78,7 +77,7 @@ class JupyterKernelWebSocket(BaseModel):
78
77
  queue_in=self._queue_in,
79
78
  queue_out=self._queue_out,
80
79
  started=started,
81
- stopped=stopped,
80
+ stopped=self._stopped
82
81
  ).run,
83
82
  daemon=True,
84
83
  name="e2b-code-interpreter-websocket",
@@ -91,7 +90,7 @@ class JupyterKernelWebSocket(BaseModel):
91
90
  while (
92
91
  not started.is_set()
93
92
  and time.time() - start_time < timeout
94
- and not self._closed
93
+ and not self._stopped.is_set()
95
94
  ):
96
95
  time.sleep(0.1)
97
96
 
@@ -245,12 +244,7 @@ class JupyterKernelWebSocket(BaseModel):
245
244
 
246
245
  def close(self):
247
246
  logger.debug("Closing WebSocket")
248
- self._closed = True
249
-
250
- for cancel in self._process_cleanup:
251
- cancel()
252
-
253
- self._process_cleanup.clear()
247
+ self._stopped.set()
254
248
 
255
249
  for handler in self._waiting_for_replies.values():
256
250
  logger.debug(f"Cancelling waiting for execution result for {handler}")
@@ -1,6 +1,6 @@
1
1
  import copy
2
2
  from typing import List, Optional, Iterable, Dict
3
- from pydantic import BaseModel
3
+ from pydantic import BaseModel, field_serializer
4
4
 
5
5
 
6
6
  class Error(BaseModel):
@@ -234,6 +234,25 @@ class Execution(BaseModel):
234
234
  if d.is_main_result:
235
235
  return d.text
236
236
 
237
+ def to_json(self) -> str:
238
+ """
239
+ Returns the JSON representation of the Execution object.
240
+ """
241
+ return self.model_dump_json(exclude_none=True)
242
+
243
+ @field_serializer("results", when_used="json")
244
+ def serialize_results(results: List[Result]) -> List[Dict[str, str]]:
245
+ """
246
+ Serializes the results to JSON.
247
+ This method is used by the Pydantic JSON encoder.
248
+ """
249
+ serialized = []
250
+ for result in results:
251
+ serialized_dict = {key: result[key] for key in result.formats()}
252
+ serialized_dict['text'] = result.text
253
+ serialized.append(serialized_dict)
254
+ return serialized
255
+
237
256
 
238
257
  class KernelException(Exception):
239
258
  """
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "e2b-code-interpreter"
3
- version = "0.0.4"
3
+ version = "0.0.6"
4
4
  description = "E2B Code Interpreter - Stateful code execution"
5
5
  authors = ["e2b <hello@e2b.dev>"]
6
6
  license = "Apache-2.0"