e2b-code-interpreter 0.0.1a0__tar.gz → 0.0.1a2__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.1a0
3
+ Version: 0.0.1a2
4
4
  Summary: E2B Code Interpreter - Stateful code execution
5
5
  Home-page: https://e2b.dev/
6
6
  License: Apache-2.0
@@ -13,6 +13,7 @@ Classifier: Programming Language :: Python :: 3.8
13
13
  Classifier: Programming Language :: Python :: 3.9
14
14
  Classifier: Programming Language :: Python :: 3.10
15
15
  Classifier: Programming Language :: Python :: 3.11
16
+ Classifier: Programming Language :: Python :: 3.12
16
17
  Requires-Dist: e2b (>=0.14.11)
17
18
  Requires-Dist: pydantic (>1,<3)
18
19
  Requires-Dist: websocket-client (>=1.7.0,<2.0.0)
@@ -43,10 +44,10 @@ pip install e2b-code-interpreter
43
44
  from e2b_code_interpreter import CodeInterpreter
44
45
 
45
46
  with CodeInterpreter() as sandbox:
46
- sandbox.exec_cell("x = 1")
47
+ sandbox.notebook.exec_cell("x = 1")
47
48
 
48
- result = sandbox.exec_cell("x += 1; x")
49
- print(result.text) # outputs 2
49
+ execution = sandbox.notebook.exec_cell("x+=1; x")
50
+ print(execution.text) # outputs 2
50
51
 
51
52
  ```
52
53
 
@@ -73,21 +74,21 @@ plt.show()
73
74
 
74
75
  with CodeInterpreter() as sandbox:
75
76
  # you can install dependencies in "jupyter notebook style"
76
- sandbox.exec_cell("!pip install matplotlib")
77
+ sandbox.notebook.exec_cell("!pip install matplotlib")
77
78
 
78
79
  # plot random graph
79
- result = sandbox.exec_cell(code)
80
+ execution = sandbox.notebook.exec_cell(code)
80
81
 
81
- # there's your image
82
- image = result.display_data[0]["image/png"]
82
+ # there's your image
83
+ image = execution.results[0].png
83
84
 
84
- # example how to show the image / prove it works
85
- i = base64.b64decode(image)
86
- i = io.BytesIO(i)
87
- i = mpimg.imread(i, format='PNG')
85
+ # example how to show the image / prove it works
86
+ i = base64.b64decode(image)
87
+ i = io.BytesIO(i)
88
+ i = mpimg.imread(i, format='PNG')
88
89
 
89
- plt.imshow(i, interpolation='nearest')
90
- plt.show()
90
+ plt.imshow(i, interpolation='nearest')
91
+ plt.show()
91
92
  ```
92
93
 
93
94
  ### Streaming code output
@@ -97,14 +98,18 @@ from e2b_code_interpreter import CodeInterpreter
97
98
 
98
99
  code = """
99
100
  import time
101
+ import pandas as pd
100
102
 
101
103
  print("hello")
102
- time.sleep(5)
104
+ time.sleep(3)
105
+ data = pd.DataFrame(data=[[1, 2], [3, 4]], columns=["A", "B"])
106
+ display(data.head(10))
107
+ time.sleep(3)
103
108
  print("world")
104
109
  """
105
110
 
106
111
  with CodeInterpreter() as sandbox:
107
- sandbox.exec_cell(code, on_stdout=print, on_stderr=print)
112
+ sandbox.notebook.exec_cell(code, on_stdout=print, on_stderr=print, on_display_data=(lambda data: print(data.text)))
108
113
  ```
109
114
 
110
115
  ### Pre-installed Python packages inside the sandbox
@@ -21,10 +21,10 @@ pip install e2b-code-interpreter
21
21
  from e2b_code_interpreter import CodeInterpreter
22
22
 
23
23
  with CodeInterpreter() as sandbox:
24
- sandbox.exec_cell("x = 1")
24
+ sandbox.notebook.exec_cell("x = 1")
25
25
 
26
- result = sandbox.exec_cell("x += 1; x")
27
- print(result.text) # outputs 2
26
+ execution = sandbox.notebook.exec_cell("x+=1; x")
27
+ print(execution.text) # outputs 2
28
28
 
29
29
  ```
30
30
 
@@ -51,21 +51,21 @@ plt.show()
51
51
 
52
52
  with CodeInterpreter() as sandbox:
53
53
  # you can install dependencies in "jupyter notebook style"
54
- sandbox.exec_cell("!pip install matplotlib")
54
+ sandbox.notebook.exec_cell("!pip install matplotlib")
55
55
 
56
56
  # plot random graph
57
- result = sandbox.exec_cell(code)
57
+ execution = sandbox.notebook.exec_cell(code)
58
58
 
59
- # there's your image
60
- image = result.display_data[0]["image/png"]
59
+ # there's your image
60
+ image = execution.results[0].png
61
61
 
62
- # example how to show the image / prove it works
63
- i = base64.b64decode(image)
64
- i = io.BytesIO(i)
65
- i = mpimg.imread(i, format='PNG')
62
+ # example how to show the image / prove it works
63
+ i = base64.b64decode(image)
64
+ i = io.BytesIO(i)
65
+ i = mpimg.imread(i, format='PNG')
66
66
 
67
- plt.imshow(i, interpolation='nearest')
68
- plt.show()
67
+ plt.imshow(i, interpolation='nearest')
68
+ plt.show()
69
69
  ```
70
70
 
71
71
  ### Streaming code output
@@ -75,14 +75,18 @@ from e2b_code_interpreter import CodeInterpreter
75
75
 
76
76
  code = """
77
77
  import time
78
+ import pandas as pd
78
79
 
79
80
  print("hello")
80
- time.sleep(5)
81
+ time.sleep(3)
82
+ data = pd.DataFrame(data=[[1, 2], [3, 4]], columns=["A", "B"])
83
+ display(data.head(10))
84
+ time.sleep(3)
81
85
  print("world")
82
86
  """
83
87
 
84
88
  with CodeInterpreter() as sandbox:
85
- sandbox.exec_cell(code, on_stdout=print, on_stderr=print)
89
+ sandbox.notebook.exec_cell(code, on_stdout=print, on_stderr=print, on_display_data=(lambda data: print(data.text)))
86
90
  ```
87
91
 
88
92
  ### Pre-installed Python packages inside the sandbox
@@ -0,0 +1,2 @@
1
+ from .main import CodeInterpreter, JupyterExtension
2
+ from .models import Execution, Error, Result, KernelException
@@ -10,7 +10,7 @@ from e2b import EnvVars, ProcessMessage, Sandbox
10
10
  from e2b.constants import TIMEOUT
11
11
 
12
12
  from e2b_code_interpreter.messaging import JupyterKernelWebSocket
13
- from e2b_code_interpreter.models import KernelException, Result
13
+ from e2b_code_interpreter.models import KernelException, Execution
14
14
 
15
15
 
16
16
  logger = logging.getLogger(__name__)
@@ -68,7 +68,7 @@ class JupyterExtension:
68
68
  on_stderr: Optional[Callable[[ProcessMessage], Any]] = None,
69
69
  on_display_data: Optional[Callable[[Dict[str, Any]], Any]] = None,
70
70
  timeout: Optional[float] = TIMEOUT,
71
- ) -> Result:
71
+ ) -> Execution:
72
72
  """
73
73
  Execute code in a notebook cell.
74
74
 
@@ -93,7 +93,9 @@ class JupyterExtension:
93
93
  logger.debug(f"Creating new websocket connection to kernel {kernel_id}")
94
94
  ws = self._connect_to_kernel_ws(kernel_id, timeout=timeout)
95
95
 
96
- session_id = ws.send_execution_message(code, on_stdout, on_stderr, on_display_data)
96
+ session_id = ws.send_execution_message(
97
+ code, on_stdout, on_stderr, on_display_data
98
+ )
97
99
  logger.debug(
98
100
  f"Sent execution message to kernel {kernel_id}, session_id: {session_id}"
99
101
  )
@@ -282,6 +284,7 @@ class JupyterExtension:
282
284
  if kernel_id is None and not self._sandbox.is_open:
283
285
  return
284
286
 
287
+ kernel_id = kernel_id.strip()
285
288
  logger.debug(f"Default kernel id: {kernel_id}")
286
289
  self._connect_to_kernel_ws(kernel_id, timeout=timeout)
287
290
  self._kernel_id_set.set_result(kernel_id)
@@ -14,7 +14,7 @@ from e2b.sandbox.websocket_client import WebSocket
14
14
  from e2b.utils.future import DeferredFuture
15
15
  from pydantic import ConfigDict, PrivateAttr, BaseModel
16
16
 
17
- from e2b_code_interpreter.models import Result, Data, Error, MIMEType
17
+ from e2b_code_interpreter.models import Execution, Result, Error, MIMEType
18
18
 
19
19
  logger = logging.getLogger(__name__)
20
20
 
@@ -36,8 +36,8 @@ class CellExecution:
36
36
  on_stderr: Optional[Callable[[ProcessMessage], None]] = None,
37
37
  on_display_data: Optional[Callable[[Dict[MIMEType, str]], None]] = None,
38
38
  ):
39
- self.partial_result = Result()
40
- self.result = Future()
39
+ self.partial_result = Execution()
40
+ self.execution = Future()
41
41
  self.on_stdout = on_stdout
42
42
  self.on_stderr = on_stderr
43
43
  self.on_display_data = on_display_data
@@ -145,8 +145,10 @@ class JupyterKernelWebSocket(BaseModel):
145
145
  self._queue_in.put(request)
146
146
  return message_id
147
147
 
148
- def get_result(self, message_id: str, timeout: Optional[float] = TIMEOUT) -> Result:
149
- result = self._cells[message_id].result.result(timeout=timeout)
148
+ def get_result(
149
+ self, message_id: str, timeout: Optional[float] = TIMEOUT
150
+ ) -> Execution:
151
+ result = self._cells[message_id].execution.result(timeout=timeout)
150
152
  logger.debug(f"Got result for message: {message_id}")
151
153
  del self._cells[message_id]
152
154
  return result
@@ -167,11 +169,11 @@ class JupyterKernelWebSocket(BaseModel):
167
169
  if not cell:
168
170
  return
169
171
 
170
- result = cell.partial_result
172
+ execution = cell.partial_result
171
173
 
172
174
  if data["msg_type"] == "error":
173
175
  logger.debug(f"Cell {parent_msg_ig} finished execution with error")
174
- result.error = Error(
176
+ execution.error = Error(
175
177
  name=data["content"]["ename"],
176
178
  value=data["content"]["evalue"],
177
179
  traceback_raw=data["content"]["traceback"],
@@ -179,7 +181,7 @@ class JupyterKernelWebSocket(BaseModel):
179
181
 
180
182
  elif data["msg_type"] == "stream":
181
183
  if data["content"]["name"] == "stdout":
182
- result.logs.stdout.append(data["content"]["text"])
184
+ execution.logs.stdout.append(data["content"]["text"])
183
185
  if cell.on_stdout:
184
186
  cell.on_stdout(
185
187
  ProcessMessage(
@@ -189,7 +191,7 @@ class JupyterKernelWebSocket(BaseModel):
189
191
  )
190
192
 
191
193
  elif data["content"]["name"] == "stderr":
192
- result.logs.stderr.append(data["content"]["text"])
194
+ execution.logs.stderr.append(data["content"]["text"])
193
195
  if cell.on_stderr:
194
196
  cell.on_stderr(
195
197
  ProcessMessage(
@@ -200,30 +202,33 @@ class JupyterKernelWebSocket(BaseModel):
200
202
  )
201
203
 
202
204
  elif data["msg_type"] in "display_data":
203
- result.data.append(Data(is_main_result=False, data=data["content"]["data"]))
205
+ result = Result(is_main_result=False, data=data["content"]["data"])
206
+ execution.results.append(result)
204
207
  if cell.on_display_data:
205
- cell.on_display_data(data["content"]["data"])
208
+ cell.on_display_data(result)
206
209
  elif data["msg_type"] == "execute_result":
207
- result.data.append(Data(is_main_result=True, data=data["content"]["data"]))
210
+ execution.results.append(
211
+ Result(is_main_result=True, data=data["content"]["data"])
212
+ )
208
213
  elif data["msg_type"] == "status":
209
214
  if data["content"]["execution_state"] == "idle":
210
215
  if cell.input_accepted:
211
216
  logger.debug(f"Cell {parent_msg_ig} finished execution")
212
- cell.result.set_result(result)
217
+ cell.execution.set_result(execution)
213
218
 
214
219
  elif data["content"]["execution_state"] == "error":
215
220
  logger.debug(f"Cell {parent_msg_ig} finished execution with error")
216
- result.error = Error(
221
+ execution.error = Error(
217
222
  name=data["content"]["ename"],
218
223
  value=data["content"]["evalue"],
219
224
  traceback_raw=data["content"]["traceback"],
220
225
  )
221
- cell.result.set_result(result)
226
+ cell.execution.set_result(execution)
222
227
 
223
228
  elif data["msg_type"] == "execute_reply":
224
229
  if data["content"]["status"] == "error":
225
230
  logger.debug(f"Cell {parent_msg_ig} finished execution with error")
226
- result.error = Error(
231
+ execution.error = Error(
227
232
  name=data["content"]["ename"],
228
233
  value=data["content"]["evalue"],
229
234
  traceback_raw=data["content"]["traceback"],
@@ -235,8 +240,7 @@ class JupyterKernelWebSocket(BaseModel):
235
240
  logger.debug(f"Input accepted for {parent_msg_ig}")
236
241
  cell.input_accepted = True
237
242
  else:
238
- logger.error(f"[UNHANDLED MESSAGE TYPE]: {data['msg_type']}")
239
- print("[UNHANDLED MESSAGE TYPE]:", data["msg_type"])
243
+ logger.warning(f"[UNHANDLED MESSAGE TYPE]: {data['msg_type']}")
240
244
 
241
245
  def close(self):
242
246
  logger.debug("Closing WebSocket")
@@ -32,20 +32,20 @@ class MIMEType(str):
32
32
  """
33
33
 
34
34
 
35
- class Data:
35
+ class Result:
36
36
  """
37
37
  Represents the data to be displayed as a result of executing a cell in a Jupyter notebook.
38
38
  This is result returned by ipython kernel: https://ipython.readthedocs.io/en/stable/development/execution.html#execution-semantics
39
39
 
40
-
41
40
  The result can contain multiple types of data, such as text, images, plots, etc. Each type of data is represented
42
41
  as a string, and the result can contain multiple types of data. The text representation is always present, and
43
42
  the other representations are optional.
44
43
 
45
44
  The class also provides methods to display the data in a Jupyter notebook.
46
45
  """
46
+
47
47
  text: str
48
- "Text representation of the data. Always present."
48
+ "Text representation of the result. Always present."
49
49
  html: Optional[str] = None
50
50
  markdown: Optional[str] = None
51
51
  svg: Optional[str] = None
@@ -180,7 +180,7 @@ class Logs(BaseModel):
180
180
  "List of strings printed to stderr by prints, subprocesses, etc."
181
181
 
182
182
 
183
- class Result(BaseModel):
183
+ class Execution(BaseModel):
184
184
  """
185
185
  Represents the result of a cell execution.
186
186
  """
@@ -188,8 +188,8 @@ class Result(BaseModel):
188
188
  class Config:
189
189
  arbitrary_types_allowed = True
190
190
 
191
- data: List[Data] = []
192
- "List of result of the cell (interactively interpreted last line), display calls, e.g. matplotlib plots."
191
+ results: List[Result] = []
192
+ "List of the result of the cell (interactively interpreted last line), display calls (e.g. matplotlib plots)."
193
193
  logs: Logs = Logs()
194
194
  "Logs printed to stdout and stderr during execution."
195
195
  error: Optional[Error] = None
@@ -202,7 +202,7 @@ class Result(BaseModel):
202
202
 
203
203
  :return: The text representation of the result.
204
204
  """
205
- for d in self.data:
205
+ for d in self.results:
206
206
  if d.is_main_result:
207
207
  return d.text
208
208
 
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "e2b-code-interpreter"
3
- version = "0.0.1a0"
3
+ version = "0.0.1a2"
4
4
  description = "E2B Code Interpreter - Stateful code execution"
5
5
  authors = ["e2b <hello@e2b.dev>"]
6
6
  license = "Apache-2.0"
@@ -1,2 +0,0 @@
1
- from .main import CodeInterpreter, JupyterExtension
2
- from .models import Result, Error, Data, KernelException