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.
- {e2b_code_interpreter-0.0.1a2 → e2b_code_interpreter-0.0.3}/PKG-INFO +2 -2
- {e2b_code_interpreter-0.0.1a2 → e2b_code_interpreter-0.0.3}/README.md +1 -1
- {e2b_code_interpreter-0.0.1a2 → e2b_code_interpreter-0.0.3}/e2b_code_interpreter/main.py +4 -7
- {e2b_code_interpreter-0.0.1a2 → e2b_code_interpreter-0.0.3}/e2b_code_interpreter/messaging.py +18 -17
- {e2b_code_interpreter-0.0.1a2 → e2b_code_interpreter-0.0.3}/e2b_code_interpreter/models.py +42 -20
- {e2b_code_interpreter-0.0.1a2 → e2b_code_interpreter-0.0.3}/pyproject.toml +1 -1
- {e2b_code_interpreter-0.0.1a2 → e2b_code_interpreter-0.0.3}/e2b_code_interpreter/__init__.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: e2b-code-interpreter
|
|
3
|
-
Version: 0.0.
|
|
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,
|
|
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,
|
|
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
|
-
|
|
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
|
|
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
|
)
|
{e2b_code_interpreter-0.0.1a2 → e2b_code_interpreter-0.0.3}/e2b_code_interpreter/messaging.py
RENAMED
|
@@ -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
|
|
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],
|
|
30
|
-
on_stderr: Optional[Callable[[ProcessMessage],
|
|
31
|
-
|
|
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],
|
|
36
|
-
on_stderr: Optional[Callable[[ProcessMessage],
|
|
37
|
-
|
|
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.
|
|
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],
|
|
133
|
-
on_stderr: Optional[Callable[[ProcessMessage],
|
|
134
|
-
|
|
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
|
-
|
|
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.
|
|
208
|
-
cell.
|
|
207
|
+
if cell.on_result:
|
|
208
|
+
cell.on_result(result)
|
|
209
209
|
elif data["msg_type"] == "execute_result":
|
|
210
|
-
|
|
211
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
82
|
+
def formats(self) -> Iterable[str]:
|
|
84
83
|
"""
|
|
85
|
-
Returns
|
|
84
|
+
Returns all available formats of the result.
|
|
86
85
|
|
|
87
|
-
:return:
|
|
86
|
+
:return: All available formats of the result in MIME types.
|
|
88
87
|
"""
|
|
89
|
-
|
|
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
|
-
|
|
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
|
|
{e2b_code_interpreter-0.0.1a2 → e2b_code_interpreter-0.0.3}/e2b_code_interpreter/__init__.py
RENAMED
|
File without changes
|