e2b-code-interpreter 0.0.1a2__tar.gz → 0.0.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,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: e2b-code-interpreter
3
- Version: 0.0.1a2
3
+ Version: 0.0.3
4
4
  Summary: E2B Code Interpreter - Stateful code execution
5
5
  Home-page: https://e2b.dev/
6
6
  License: Apache-2.0
@@ -109,7 +109,7 @@ print("world")
109
109
  """
110
110
 
111
111
  with CodeInterpreter() as sandbox:
112
- sandbox.notebook.exec_cell(code, on_stdout=print, on_stderr=print, on_display_data=(lambda data: print(data.text)))
112
+ sandbox.notebook.exec_cell(code, on_stdout=print, on_stderr=print, on_result=(lambda result: print(result.text)))
113
113
  ```
114
114
 
115
115
  ### Pre-installed Python packages inside the sandbox
@@ -86,7 +86,7 @@ print("world")
86
86
  """
87
87
 
88
88
  with CodeInterpreter() as sandbox:
89
- sandbox.notebook.exec_cell(code, on_stdout=print, on_stderr=print, on_display_data=(lambda data: print(data.text)))
89
+ sandbox.notebook.exec_cell(code, on_stdout=print, on_stderr=print, on_result=(lambda result: print(result.text)))
90
90
  ```
91
91
 
92
92
  ### Pre-installed Python packages inside the sandbox
@@ -10,8 +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, Execution
14
-
13
+ from e2b_code_interpreter.models import KernelException, Execution, Result
15
14
 
16
15
  logger = logging.getLogger(__name__)
17
16
 
@@ -66,7 +65,7 @@ class JupyterExtension:
66
65
  kernel_id: Optional[str] = None,
67
66
  on_stdout: Optional[Callable[[ProcessMessage], Any]] = None,
68
67
  on_stderr: Optional[Callable[[ProcessMessage], Any]] = None,
69
- on_display_data: Optional[Callable[[Dict[str, Any]], Any]] = None,
68
+ on_result: Optional[Callable[[Result], Any]] = None,
70
69
  timeout: Optional[float] = TIMEOUT,
71
70
  ) -> Execution:
72
71
  """
@@ -76,7 +75,7 @@ class JupyterExtension:
76
75
  :param kernel_id: The ID of the kernel to execute the code on. If not provided, the default kernel is used.
77
76
  :param on_stdout: A callback function to handle standard output messages from the code execution.
78
77
  :param on_stderr: A callback function to handle standard error messages from the code execution.
79
- :param on_display_data: A callback function to handle display data messages from the code execution.
78
+ :param on_result: A callback function to handle the result and display calls of the code execution.
80
79
  :param timeout: Timeout for the call
81
80
 
82
81
  :return: Result of the execution
@@ -93,9 +92,7 @@ class JupyterExtension:
93
92
  logger.debug(f"Creating new websocket connection to kernel {kernel_id}")
94
93
  ws = self._connect_to_kernel_ws(kernel_id, timeout=timeout)
95
94
 
96
- session_id = ws.send_execution_message(
97
- code, on_stdout, on_stderr, on_display_data
98
- )
95
+ session_id = ws.send_execution_message(code, on_stdout, on_stderr, on_result)
99
96
  logger.debug(
100
97
  f"Sent execution message to kernel {kernel_id}, session_id: {session_id}"
101
98
  )
@@ -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 Execution, Result, Error, MIMEType
17
+ from e2b_code_interpreter.models import Execution, Result, Error
18
18
 
19
19
  logger = logging.getLogger(__name__)
20
20
 
@@ -26,21 +26,21 @@ class CellExecution:
26
26
  """
27
27
 
28
28
  input_accepted: bool = False
29
- on_stdout: Optional[Callable[[ProcessMessage], None]] = None
30
- on_stderr: Optional[Callable[[ProcessMessage], None]] = None
31
- on_display_data: Optional[Callable[[Dict[MIMEType, str]], None]] = None
29
+ on_stdout: Optional[Callable[[ProcessMessage], Any]] = None
30
+ on_stderr: Optional[Callable[[ProcessMessage], Any]] = None
31
+ on_result: Optional[Callable[[Result], Any]] = None
32
32
 
33
33
  def __init__(
34
34
  self,
35
- on_stdout: Optional[Callable[[ProcessMessage], None]] = None,
36
- on_stderr: Optional[Callable[[ProcessMessage], None]] = None,
37
- on_display_data: Optional[Callable[[Dict[MIMEType, str]], None]] = None,
35
+ on_stdout: Optional[Callable[[ProcessMessage], Any]] = None,
36
+ on_stderr: Optional[Callable[[ProcessMessage], Any]] = None,
37
+ on_result: Optional[Callable[[Result], Any]] = None,
38
38
  ):
39
39
  self.partial_result = Execution()
40
40
  self.execution = Future()
41
41
  self.on_stdout = on_stdout
42
42
  self.on_stderr = on_stderr
43
- self.on_display_data = on_display_data
43
+ self.on_result = on_result
44
44
 
45
45
 
46
46
  class JupyterKernelWebSocket(BaseModel):
@@ -129,9 +129,9 @@ class JupyterKernelWebSocket(BaseModel):
129
129
  def send_execution_message(
130
130
  self,
131
131
  code: str,
132
- on_stdout: Optional[Callable[[ProcessMessage], None]] = None,
133
- on_stderr: Optional[Callable[[ProcessMessage], None]] = None,
134
- on_display_data: Optional[Callable[[Dict[MIMEType, str]], None]] = None,
132
+ on_stdout: Optional[Callable[[ProcessMessage], Any]] = None,
133
+ on_stderr: Optional[Callable[[ProcessMessage], Any]] = None,
134
+ on_result: Optional[Callable[[Result], Any]] = None,
135
135
  ) -> str:
136
136
  message_id = str(uuid.uuid4())
137
137
  logger.debug(f"Sending execution message: {message_id}")
@@ -139,7 +139,7 @@ class JupyterKernelWebSocket(BaseModel):
139
139
  self._cells[message_id] = CellExecution(
140
140
  on_stdout=on_stdout,
141
141
  on_stderr=on_stderr,
142
- on_display_data=on_display_data,
142
+ on_result=on_result,
143
143
  )
144
144
  request = self._get_execute_request(message_id, code)
145
145
  self._queue_in.put(request)
@@ -204,12 +204,13 @@ class JupyterKernelWebSocket(BaseModel):
204
204
  elif data["msg_type"] in "display_data":
205
205
  result = Result(is_main_result=False, data=data["content"]["data"])
206
206
  execution.results.append(result)
207
- if cell.on_display_data:
208
- cell.on_display_data(result)
207
+ if cell.on_result:
208
+ cell.on_result(result)
209
209
  elif data["msg_type"] == "execute_result":
210
- execution.results.append(
211
- Result(is_main_result=True, data=data["content"]["data"])
212
- )
210
+ result = Result(is_main_result=True, data=data["content"]["data"])
211
+ execution.results.append(result)
212
+ if cell.on_result:
213
+ cell.on_result(result)
213
214
  elif data["msg_type"] == "status":
214
215
  if data["content"]["execution_state"] == "idle":
215
216
  if cell.input_accepted:
@@ -35,17 +35,16 @@ class MIMEType(str):
35
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
- This is result returned by ipython kernel: https://ipython.readthedocs.io/en/stable/development/execution.html#execution-semantics
38
+ The result is similar to the structure returned by ipython kernel: https://ipython.readthedocs.io/en/stable/development/execution.html#execution-semantics
39
39
 
40
40
  The result can contain multiple types of data, such as text, images, plots, etc. Each type of data is represented
41
- as a string, and the result can contain multiple types of data. The text representation is always present, and
42
- the other representations are optional.
41
+ as a string, and the result can contain multiple types of data. The display calls don't have to have text representation,
42
+ for the actual result the representation is always present for the result, the other representations are always optional.
43
43
 
44
44
  The class also provides methods to display the data in a Jupyter notebook.
45
45
  """
46
46
 
47
- text: str
48
- "Text representation of the result. Always present."
47
+ text: Optional[str] = None
49
48
  html: Optional[str] = None
50
49
  markdown: Optional[str] = None
51
50
  svg: Optional[str] = None
@@ -68,7 +67,7 @@ class Result:
68
67
  self.is_main_result = is_main_result
69
68
  self.raw = copy.deepcopy(data)
70
69
 
71
- self.text = data.pop("text/plain")
70
+ self.text = data.pop("text/plain", None)
72
71
  self.html = data.pop("text/html", None)
73
72
  self.markdown = data.pop("text/markdown", None)
74
73
  self.svg = data.pop("image/svg+xml", None)
@@ -80,15 +79,38 @@ class Result:
80
79
  self.javascript = data.pop("application/javascript", None)
81
80
  self.extra = data
82
81
 
83
- def keys(self) -> Iterable[str]:
82
+ def formats(self) -> Iterable[str]:
84
83
  """
85
- Returns the MIME types of the data.
84
+ Returns all available formats of the result.
86
85
 
87
- :return: The MIME types of the data.
86
+ :return: All available formats of the result in MIME types.
88
87
  """
89
- return self.raw.keys()
88
+ formats = []
89
+ if self.html:
90
+ formats.append("html")
91
+ if self.markdown:
92
+ formats.append("markdown")
93
+ if self.svg:
94
+ formats.append("svg")
95
+ if self.png:
96
+ formats.append("png")
97
+ if self.jpeg:
98
+ formats.append("jpeg")
99
+ if self.pdf:
100
+ formats.append("pdf")
101
+ if self.latex:
102
+ formats.append("latex")
103
+ if self.json:
104
+ formats.append("json")
105
+ if self.javascript:
106
+ formats.append("javascript")
90
107
 
91
- def __str__(self) -> str:
108
+ for key in self.extra:
109
+ formats.append(key)
110
+
111
+ return formats
112
+
113
+ def __str__(self) -> Optional[str]:
92
114
  """
93
115
  Returns the text representation of the data.
94
116
 
@@ -96,7 +118,7 @@ class Result:
96
118
  """
97
119
  return self.text
98
120
 
99
- def _repr_html_(self) -> str:
121
+ def _repr_html_(self) -> Optional[str]:
100
122
  """
101
123
  Returns the HTML representation of the data.
102
124
 
@@ -104,7 +126,7 @@ class Result:
104
126
  """
105
127
  return self.html
106
128
 
107
- def _repr_markdown_(self) -> str:
129
+ def _repr_markdown_(self) -> Optional[str]:
108
130
  """
109
131
  Returns the Markdown representation of the data.
110
132
 
@@ -112,7 +134,7 @@ class Result:
112
134
  """
113
135
  return self.markdown
114
136
 
115
- def _repr_svg_(self) -> str:
137
+ def _repr_svg_(self) -> Optional[str]:
116
138
  """
117
139
  Returns the SVG representation of the data.
118
140
 
@@ -120,7 +142,7 @@ class Result:
120
142
  """
121
143
  return self.svg
122
144
 
123
- def _repr_png_(self) -> str:
145
+ def _repr_png_(self) -> Optional[str]:
124
146
  """
125
147
  Returns the base64 representation of the PNG data.
126
148
 
@@ -128,7 +150,7 @@ class Result:
128
150
  """
129
151
  return self.png
130
152
 
131
- def _repr_jpeg_(self) -> str:
153
+ def _repr_jpeg_(self) -> Optional[str]:
132
154
  """
133
155
  Returns the base64 representation of the JPEG data.
134
156
 
@@ -136,7 +158,7 @@ class Result:
136
158
  """
137
159
  return self.jpeg
138
160
 
139
- def _repr_pdf_(self) -> str:
161
+ def _repr_pdf_(self) -> Optional[str]:
140
162
  """
141
163
  Returns the PDF representation of the data.
142
164
 
@@ -144,7 +166,7 @@ class Result:
144
166
  """
145
167
  return self.pdf
146
168
 
147
- def _repr_latex_(self) -> str:
169
+ def _repr_latex_(self) -> Optional[str]:
148
170
  """
149
171
  Returns the LaTeX representation of the data.
150
172
 
@@ -152,7 +174,7 @@ class Result:
152
174
  """
153
175
  return self.latex
154
176
 
155
- def _repr_json_(self) -> dict:
177
+ def _repr_json_(self) -> Optional[dict]:
156
178
  """
157
179
  Returns the JSON representation of the data.
158
180
 
@@ -160,7 +182,7 @@ class Result:
160
182
  """
161
183
  return self.json
162
184
 
163
- def _repr_javascript_(self) -> str:
185
+ def _repr_javascript_(self) -> Optional[str]:
164
186
  """
165
187
  Returns the JavaScript representation of the data.
166
188
 
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "e2b-code-interpreter"
3
- version = "0.0.1a2"
3
+ version = "0.0.3"
4
4
  description = "E2B Code Interpreter - Stateful code execution"
5
5
  authors = ["e2b <hello@e2b.dev>"]
6
6
  license = "Apache-2.0"