e2b-code-interpreter 0.0.11b47__tar.gz → 1.0.0__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.11b47 → e2b_code_interpreter-1.0.0}/PKG-INFO +44 -8
- e2b_code_interpreter-1.0.0/README.md +127 -0
- e2b_code_interpreter-0.0.11b47/e2b_code_interpreter/graphs.py → e2b_code_interpreter-1.0.0/e2b_code_interpreter/charts.py +40 -40
- {e2b_code_interpreter-0.0.11b47 → e2b_code_interpreter-1.0.0}/e2b_code_interpreter/code_interpreter_async.py +105 -22
- {e2b_code_interpreter-0.0.11b47 → e2b_code_interpreter-1.0.0}/e2b_code_interpreter/code_interpreter_sync.py +105 -22
- {e2b_code_interpreter-0.0.11b47 → e2b_code_interpreter-1.0.0}/e2b_code_interpreter/constants.py +1 -1
- {e2b_code_interpreter-0.0.11b47 → e2b_code_interpreter-1.0.0}/e2b_code_interpreter/models.py +43 -8
- {e2b_code_interpreter-0.0.11b47 → e2b_code_interpreter-1.0.0}/pyproject.toml +2 -2
- e2b_code_interpreter-0.0.11b47/README.md +0 -90
- {e2b_code_interpreter-0.0.11b47 → e2b_code_interpreter-1.0.0}/e2b_code_interpreter/__init__.py +0 -0
- {e2b_code_interpreter-0.0.11b47 → e2b_code_interpreter-1.0.0}/e2b_code_interpreter/exceptions.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: 1.0.0
|
|
4
4
|
Summary: E2B Code Interpreter - Stateful code execution
|
|
5
5
|
Home-page: https://e2b.dev/
|
|
6
6
|
License: Apache-2.0
|
|
@@ -15,20 +15,38 @@ Classifier: Programming Language :: Python :: 3.10
|
|
|
15
15
|
Classifier: Programming Language :: Python :: 3.11
|
|
16
16
|
Classifier: Programming Language :: Python :: 3.12
|
|
17
17
|
Requires-Dist: attrs (>=21.3.0)
|
|
18
|
-
Requires-Dist: e2b (>=0.
|
|
18
|
+
Requires-Dist: e2b (>=1.0.0,<2.0.0)
|
|
19
19
|
Requires-Dist: httpx (>=0.20.0,<0.28.0)
|
|
20
20
|
Project-URL: Bug Tracker, https://github.com/e2b-dev/code-interpreter/issues
|
|
21
21
|
Project-URL: Repository, https://github.com/e2b-dev/e2b-code-interpreter/tree/python
|
|
22
22
|
Description-Content-Type: text/markdown
|
|
23
23
|
|
|
24
|
-
|
|
24
|
+
<p align="center">
|
|
25
|
+
<img width="100" src="/readme-assets/logo-circle.png" alt="e2b logo">
|
|
26
|
+
</p>
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
<h1 align="center">
|
|
30
|
+
Code interpreter extension for Python
|
|
31
|
+
</h1>
|
|
32
|
+
|
|
33
|
+
<h4 align="center">
|
|
34
|
+
<a href="https://pypi.org/project/e2b/">
|
|
35
|
+
<img alt="Last 1 month downloads for the Python SDK" loading="lazy" width="200" height="20" decoding="async" data-nimg="1"
|
|
36
|
+
style="color:transparent;width:auto;height:100%" src="https://img.shields.io/pypi/dm/e2b?label=PyPI%20Downloads">
|
|
37
|
+
</a>
|
|
38
|
+
<a href="https://www.npmjs.com/package/e2b">
|
|
39
|
+
<img alt="Last 1 month downloads for the Python SDK" loading="lazy" width="200" height="20" decoding="async" data-nimg="1"
|
|
40
|
+
style="color:transparent;width:auto;height:100%" src="https://img.shields.io/npm/dm/e2b?label=NPM%20Downloads">
|
|
41
|
+
</a>
|
|
42
|
+
</h4>
|
|
25
43
|
|
|
26
44
|
The repository contains a template and modules for the code interpreter sandbox. It is based on the Jupyter server and implements the Jupyter Kernel messaging protocol. This allows for sharing context between code executions and improves support for plotting charts and other display-able data.
|
|
27
45
|
|
|
28
46
|
## Key Features
|
|
29
47
|
|
|
30
48
|
- **Stateful Execution**: Unlike traditional sandboxes that treat each code execution independently, this package maintains context across executions.
|
|
31
|
-
- **Displaying
|
|
49
|
+
- **Displaying Charts & Data**: Implements parts of the [Jupyter Kernel messaging protocol](https://jupyter-client.readthedocs.io/en/latest/messaging.html), which support for interactive features like plotting charts, rendering DataFrames, etc.
|
|
32
50
|
|
|
33
51
|
## Installation
|
|
34
52
|
|
|
@@ -44,11 +62,10 @@ pip install e2b-code-interpreter
|
|
|
44
62
|
from e2b_code_interpreter import Sandbox
|
|
45
63
|
|
|
46
64
|
with Sandbox() as sandbox:
|
|
47
|
-
sandbox.run_code("x = 1")
|
|
65
|
+
sandbox.run_code()("x = 1")
|
|
48
66
|
|
|
49
|
-
execution = sandbox.run_code("x+=1; x")
|
|
67
|
+
execution = sandbox.run_code()("x+=1; x")
|
|
50
68
|
print(execution.text) # outputs 2
|
|
51
|
-
|
|
52
69
|
```
|
|
53
70
|
|
|
54
71
|
### Get charts and any display-able data
|
|
@@ -76,7 +93,7 @@ with Sandbox() as sandbox:
|
|
|
76
93
|
# you can install dependencies in "jupyter notebook style"
|
|
77
94
|
sandbox.run_code("!pip install matplotlib")
|
|
78
95
|
|
|
79
|
-
# plot random
|
|
96
|
+
# plot random chart
|
|
80
97
|
execution = sandbox.run_code(code)
|
|
81
98
|
|
|
82
99
|
# there's your image
|
|
@@ -112,3 +129,22 @@ with Sandbox() as sandbox:
|
|
|
112
129
|
sandbox.run_code(code, on_stdout=print, on_stderr=print, on_result=(lambda result: print(result.text)))
|
|
113
130
|
```
|
|
114
131
|
|
|
132
|
+
### More resources
|
|
133
|
+
- Check out the [JavaScript/TypeScript](https://e2b.dev/docs/hello-world/js) and [Python](https://e2b.dev/docs/hello-world/py) "Hello World" guides to learn how to use our SDK.
|
|
134
|
+
|
|
135
|
+
- See [E2B documentation](https://e2b.dev/docs) to get started.
|
|
136
|
+
|
|
137
|
+
- Visit our [Cookbook](https://github.com/e2b-dev/e2b-cookbook/tree/main) to get inspired by examples with different LLMs and AI frameworks.
|
|
138
|
+
|
|
139
|
+
___
|
|
140
|
+
|
|
141
|
+
<div align='center'>
|
|
142
|
+
<!-- <a href="https://e2b.dev/docs" target="_blank">
|
|
143
|
+
<img src="https://img.shields.io/badge/docs-%2300acee.svg?color=143D52&style=for-the-badge&logo=x&logoColor=white" alt=docs style="margin-bottom: 5px;"/></a> -->
|
|
144
|
+
<a href="https://twitter.com/e2b_dev" target="_blank">
|
|
145
|
+
<img src="https://img.shields.io/badge/x (twitter)-%2300acee.svg?color=000000&style=for-the-badge&logo=x&logoColor=white" alt=linkedin style="margin-bottom: 5px;"/></a>
|
|
146
|
+
<a href="https://discord.com/invite/U7KEcGErtQ" target="_blank">
|
|
147
|
+
<img src="https://img.shields.io/badge/discord -%2300acee.svg?color=143D52&style=for-the-badge&logo=discord&logoColor=white" alt=discord style="margin-bottom: 5px;"/></a>
|
|
148
|
+
<a href="https://www.linkedin.com/company/e2b-dev/" target="_blank">
|
|
149
|
+
<img src="https://img.shields.io/badge/linkedin-%2300acee.svg?color=000000&style=for-the-badge&logo=linkedin&logoColor=white" alt=linkedin style="margin-bottom: 5px;"/></a>
|
|
150
|
+
</div align='center'>
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img width="100" src="/readme-assets/logo-circle.png" alt="e2b logo">
|
|
3
|
+
</p>
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
<h1 align="center">
|
|
7
|
+
Code interpreter extension for Python
|
|
8
|
+
</h1>
|
|
9
|
+
|
|
10
|
+
<h4 align="center">
|
|
11
|
+
<a href="https://pypi.org/project/e2b/">
|
|
12
|
+
<img alt="Last 1 month downloads for the Python SDK" loading="lazy" width="200" height="20" decoding="async" data-nimg="1"
|
|
13
|
+
style="color:transparent;width:auto;height:100%" src="https://img.shields.io/pypi/dm/e2b?label=PyPI%20Downloads">
|
|
14
|
+
</a>
|
|
15
|
+
<a href="https://www.npmjs.com/package/e2b">
|
|
16
|
+
<img alt="Last 1 month downloads for the Python SDK" loading="lazy" width="200" height="20" decoding="async" data-nimg="1"
|
|
17
|
+
style="color:transparent;width:auto;height:100%" src="https://img.shields.io/npm/dm/e2b?label=NPM%20Downloads">
|
|
18
|
+
</a>
|
|
19
|
+
</h4>
|
|
20
|
+
|
|
21
|
+
The repository contains a template and modules for the code interpreter sandbox. It is based on the Jupyter server and implements the Jupyter Kernel messaging protocol. This allows for sharing context between code executions and improves support for plotting charts and other display-able data.
|
|
22
|
+
|
|
23
|
+
## Key Features
|
|
24
|
+
|
|
25
|
+
- **Stateful Execution**: Unlike traditional sandboxes that treat each code execution independently, this package maintains context across executions.
|
|
26
|
+
- **Displaying Charts & Data**: Implements parts of the [Jupyter Kernel messaging protocol](https://jupyter-client.readthedocs.io/en/latest/messaging.html), which support for interactive features like plotting charts, rendering DataFrames, etc.
|
|
27
|
+
|
|
28
|
+
## Installation
|
|
29
|
+
|
|
30
|
+
```sh
|
|
31
|
+
pip install e2b-code-interpreter
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Examples
|
|
35
|
+
|
|
36
|
+
### Minimal example with the sharing context
|
|
37
|
+
|
|
38
|
+
```python
|
|
39
|
+
from e2b_code_interpreter import Sandbox
|
|
40
|
+
|
|
41
|
+
with Sandbox() as sandbox:
|
|
42
|
+
sandbox.run_code()("x = 1")
|
|
43
|
+
|
|
44
|
+
execution = sandbox.run_code()("x+=1; x")
|
|
45
|
+
print(execution.text) # outputs 2
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### Get charts and any display-able data
|
|
49
|
+
|
|
50
|
+
```python
|
|
51
|
+
import base64
|
|
52
|
+
import io
|
|
53
|
+
|
|
54
|
+
from matplotlib import image as mpimg, pyplot as plt
|
|
55
|
+
|
|
56
|
+
from e2b_code_interpreter import Sandbox
|
|
57
|
+
|
|
58
|
+
code = """
|
|
59
|
+
import matplotlib.pyplot as plt
|
|
60
|
+
import numpy as np
|
|
61
|
+
|
|
62
|
+
x = np.linspace(0, 20, 100)
|
|
63
|
+
y = np.sin(x)
|
|
64
|
+
|
|
65
|
+
plt.plot(x, y)
|
|
66
|
+
plt.show()
|
|
67
|
+
"""
|
|
68
|
+
|
|
69
|
+
with Sandbox() as sandbox:
|
|
70
|
+
# you can install dependencies in "jupyter notebook style"
|
|
71
|
+
sandbox.run_code("!pip install matplotlib")
|
|
72
|
+
|
|
73
|
+
# plot random chart
|
|
74
|
+
execution = sandbox.run_code(code)
|
|
75
|
+
|
|
76
|
+
# there's your image
|
|
77
|
+
image = execution.results[0].png
|
|
78
|
+
|
|
79
|
+
# example how to show the image / prove it works
|
|
80
|
+
i = base64.b64decode(image)
|
|
81
|
+
i = io.BytesIO(i)
|
|
82
|
+
i = mpimg.imread(i, format='PNG')
|
|
83
|
+
|
|
84
|
+
plt.imshow(i, interpolation='nearest')
|
|
85
|
+
plt.show()
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### Streaming code output
|
|
89
|
+
|
|
90
|
+
```python
|
|
91
|
+
from e2b_code_interpreter import Sandbox
|
|
92
|
+
|
|
93
|
+
code = """
|
|
94
|
+
import time
|
|
95
|
+
import pandas as pd
|
|
96
|
+
|
|
97
|
+
print("hello")
|
|
98
|
+
time.sleep(3)
|
|
99
|
+
data = pd.DataFrame(data=[[1, 2], [3, 4]], columns=["A", "B"])
|
|
100
|
+
display(data.head(10))
|
|
101
|
+
time.sleep(3)
|
|
102
|
+
print("world")
|
|
103
|
+
"""
|
|
104
|
+
|
|
105
|
+
with Sandbox() as sandbox:
|
|
106
|
+
sandbox.run_code(code, on_stdout=print, on_stderr=print, on_result=(lambda result: print(result.text)))
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### More resources
|
|
110
|
+
- Check out the [JavaScript/TypeScript](https://e2b.dev/docs/hello-world/js) and [Python](https://e2b.dev/docs/hello-world/py) "Hello World" guides to learn how to use our SDK.
|
|
111
|
+
|
|
112
|
+
- See [E2B documentation](https://e2b.dev/docs) to get started.
|
|
113
|
+
|
|
114
|
+
- Visit our [Cookbook](https://github.com/e2b-dev/e2b-cookbook/tree/main) to get inspired by examples with different LLMs and AI frameworks.
|
|
115
|
+
|
|
116
|
+
___
|
|
117
|
+
|
|
118
|
+
<div align='center'>
|
|
119
|
+
<!-- <a href="https://e2b.dev/docs" target="_blank">
|
|
120
|
+
<img src="https://img.shields.io/badge/docs-%2300acee.svg?color=143D52&style=for-the-badge&logo=x&logoColor=white" alt=docs style="margin-bottom: 5px;"/></a> -->
|
|
121
|
+
<a href="https://twitter.com/e2b_dev" target="_blank">
|
|
122
|
+
<img src="https://img.shields.io/badge/x (twitter)-%2300acee.svg?color=000000&style=for-the-badge&logo=x&logoColor=white" alt=linkedin style="margin-bottom: 5px;"/></a>
|
|
123
|
+
<a href="https://discord.com/invite/U7KEcGErtQ" target="_blank">
|
|
124
|
+
<img src="https://img.shields.io/badge/discord -%2300acee.svg?color=143D52&style=for-the-badge&logo=discord&logoColor=white" alt=discord style="margin-bottom: 5px;"/></a>
|
|
125
|
+
<a href="https://www.linkedin.com/company/e2b-dev/" target="_blank">
|
|
126
|
+
<img src="https://img.shields.io/badge/linkedin-%2300acee.svg?color=000000&style=for-the-badge&logo=linkedin&logoColor=white" alt=linkedin style="margin-bottom: 5px;"/></a>
|
|
127
|
+
</div align='center'>
|
|
@@ -2,9 +2,9 @@ import enum
|
|
|
2
2
|
from typing import List, Tuple, Any, Optional, Union
|
|
3
3
|
|
|
4
4
|
|
|
5
|
-
class
|
|
5
|
+
class ChartType(str, enum.Enum):
|
|
6
6
|
"""
|
|
7
|
-
|
|
7
|
+
Chart types
|
|
8
8
|
"""
|
|
9
9
|
|
|
10
10
|
LINE = "line"
|
|
@@ -12,7 +12,7 @@ class GraphType(str, enum.Enum):
|
|
|
12
12
|
BAR = "bar"
|
|
13
13
|
PIE = "pie"
|
|
14
14
|
BOX_AND_WHISKER = "box_and_whisker"
|
|
15
|
-
|
|
15
|
+
SUPERCHART = "superchart"
|
|
16
16
|
UNKNOWN = "unknown"
|
|
17
17
|
|
|
18
18
|
|
|
@@ -33,23 +33,23 @@ class ScaleType(str, enum.Enum):
|
|
|
33
33
|
UNKNOWN = "unknown"
|
|
34
34
|
|
|
35
35
|
|
|
36
|
-
class
|
|
36
|
+
class Chart:
|
|
37
37
|
"""
|
|
38
|
-
Extracted data from a
|
|
38
|
+
Extracted data from a chart. It's useful for building an interactive charts or custom visualizations.
|
|
39
39
|
"""
|
|
40
40
|
|
|
41
|
-
type:
|
|
41
|
+
type: ChartType
|
|
42
42
|
title: str
|
|
43
43
|
|
|
44
44
|
elements: List[Any]
|
|
45
45
|
|
|
46
46
|
def __init__(self, **kwargs):
|
|
47
|
-
self.type =
|
|
47
|
+
self.type = ChartType(kwargs["type"] or ChartType.UNKNOWN)
|
|
48
48
|
self.title = kwargs["title"]
|
|
49
49
|
self.elements = kwargs["elements"]
|
|
50
50
|
|
|
51
51
|
|
|
52
|
-
class
|
|
52
|
+
class Chart2D(Chart):
|
|
53
53
|
x_label: Optional[str]
|
|
54
54
|
y_label: Optional[str]
|
|
55
55
|
x_unit: Optional[str]
|
|
@@ -72,7 +72,7 @@ class PointData:
|
|
|
72
72
|
self.points = [(x, y) for x, y in kwargs["points"]]
|
|
73
73
|
|
|
74
74
|
|
|
75
|
-
class
|
|
75
|
+
class PointChart(Chart2D):
|
|
76
76
|
x_ticks: List[Union[str, float]]
|
|
77
77
|
x_tick_labels: List[str]
|
|
78
78
|
x_scale: ScaleType
|
|
@@ -108,12 +108,12 @@ class PointGraph(Graph2D):
|
|
|
108
108
|
self.elements = [PointData(**d) for d in kwargs["elements"]]
|
|
109
109
|
|
|
110
110
|
|
|
111
|
-
class
|
|
112
|
-
type =
|
|
111
|
+
class LineChart(PointChart):
|
|
112
|
+
type = ChartType.LINE
|
|
113
113
|
|
|
114
114
|
|
|
115
|
-
class
|
|
116
|
-
type =
|
|
115
|
+
class ScatterChart(PointChart):
|
|
116
|
+
type = ChartType.SCATTER
|
|
117
117
|
|
|
118
118
|
|
|
119
119
|
class BarData:
|
|
@@ -127,8 +127,8 @@ class BarData:
|
|
|
127
127
|
self.group = kwargs["group"]
|
|
128
128
|
|
|
129
129
|
|
|
130
|
-
class
|
|
131
|
-
type =
|
|
130
|
+
class BarChart(Chart2D):
|
|
131
|
+
type = ChartType.BAR
|
|
132
132
|
|
|
133
133
|
elements: List[BarData]
|
|
134
134
|
|
|
@@ -148,8 +148,8 @@ class PieData:
|
|
|
148
148
|
self.radius = kwargs["radius"]
|
|
149
149
|
|
|
150
150
|
|
|
151
|
-
class
|
|
152
|
-
type =
|
|
151
|
+
class PieChart(Chart):
|
|
152
|
+
type = ChartType.PIE
|
|
153
153
|
|
|
154
154
|
elements: List[PieData]
|
|
155
155
|
|
|
@@ -175,8 +175,8 @@ class BoxAndWhiskerData:
|
|
|
175
175
|
self.max = kwargs["max"]
|
|
176
176
|
|
|
177
177
|
|
|
178
|
-
class
|
|
179
|
-
type =
|
|
178
|
+
class BoxAndWhiskerChart(Chart2D):
|
|
179
|
+
type = ChartType.BOX_AND_WHISKER
|
|
180
180
|
|
|
181
181
|
elements: List[BoxAndWhiskerData]
|
|
182
182
|
|
|
@@ -185,40 +185,40 @@ class BoxAndWhiskerGraph(Graph2D):
|
|
|
185
185
|
self.elements = [BoxAndWhiskerData(**d) for d in kwargs["elements"]]
|
|
186
186
|
|
|
187
187
|
|
|
188
|
-
class
|
|
189
|
-
type =
|
|
188
|
+
class SuperChart(Chart):
|
|
189
|
+
type = ChartType.SUPERCHART
|
|
190
190
|
|
|
191
191
|
elements: List[
|
|
192
|
-
Union[
|
|
192
|
+
Union[LineChart, ScatterChart, BarChart, PieChart, BoxAndWhiskerChart]
|
|
193
193
|
]
|
|
194
194
|
|
|
195
195
|
def __init__(self, **kwargs):
|
|
196
196
|
super().__init__(**kwargs)
|
|
197
|
-
self.elements = [
|
|
197
|
+
self.elements = [_deserialize_chart(g) for g in kwargs["elements"]]
|
|
198
198
|
|
|
199
199
|
|
|
200
|
-
|
|
201
|
-
|
|
200
|
+
ChartTypes = Union[
|
|
201
|
+
LineChart, ScatterChart, BarChart, PieChart, BoxAndWhiskerChart, SuperChart
|
|
202
202
|
]
|
|
203
203
|
|
|
204
204
|
|
|
205
|
-
def
|
|
205
|
+
def _deserialize_chart(data: Optional[dict]) -> Optional[ChartTypes]:
|
|
206
206
|
if not data:
|
|
207
207
|
return None
|
|
208
208
|
|
|
209
|
-
if data["type"] ==
|
|
210
|
-
|
|
211
|
-
elif data["type"] ==
|
|
212
|
-
|
|
213
|
-
elif data["type"] ==
|
|
214
|
-
|
|
215
|
-
elif data["type"] ==
|
|
216
|
-
|
|
217
|
-
elif data["type"] ==
|
|
218
|
-
|
|
219
|
-
elif data["type"] ==
|
|
220
|
-
|
|
209
|
+
if data["type"] == ChartType.LINE:
|
|
210
|
+
chart = LineChart(**data)
|
|
211
|
+
elif data["type"] == ChartType.SCATTER:
|
|
212
|
+
chart = ScatterChart(**data)
|
|
213
|
+
elif data["type"] == ChartType.BAR:
|
|
214
|
+
chart = BarChart(**data)
|
|
215
|
+
elif data["type"] == ChartType.PIE:
|
|
216
|
+
chart = PieChart(**data)
|
|
217
|
+
elif data["type"] == ChartType.BOX_AND_WHISKER:
|
|
218
|
+
chart = BoxAndWhiskerChart(**data)
|
|
219
|
+
elif data["type"] == ChartType.SUPERCHART:
|
|
220
|
+
chart = SuperChart(**data)
|
|
221
221
|
else:
|
|
222
|
-
|
|
222
|
+
chart = Chart(**data)
|
|
223
223
|
|
|
224
|
-
return
|
|
224
|
+
return chart
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import logging
|
|
2
2
|
import httpx
|
|
3
3
|
|
|
4
|
-
from typing import Optional, Dict, overload
|
|
4
|
+
from typing import Optional, Dict, overload, Union, Literal
|
|
5
5
|
from httpx import AsyncClient
|
|
6
6
|
|
|
7
7
|
from e2b import (
|
|
@@ -17,6 +17,7 @@ from e2b_code_interpreter.constants import (
|
|
|
17
17
|
)
|
|
18
18
|
from e2b_code_interpreter.models import (
|
|
19
19
|
Execution,
|
|
20
|
+
ExecutionError,
|
|
20
21
|
Context,
|
|
21
22
|
Result,
|
|
22
23
|
aextract_exception,
|
|
@@ -33,6 +34,27 @@ logger = logging.getLogger(__name__)
|
|
|
33
34
|
|
|
34
35
|
|
|
35
36
|
class AsyncSandbox(BaseAsyncSandbox):
|
|
37
|
+
"""
|
|
38
|
+
E2B cloud sandbox is a secure and isolated cloud environment.
|
|
39
|
+
|
|
40
|
+
The sandbox allows you to:
|
|
41
|
+
- Access Linux OS
|
|
42
|
+
- Create, list, and delete files and directories
|
|
43
|
+
- Run commands
|
|
44
|
+
- Run isolated code
|
|
45
|
+
- Access the internet
|
|
46
|
+
|
|
47
|
+
Check docs [here](https://e2b.dev/docs).
|
|
48
|
+
|
|
49
|
+
Use the `AsyncSandbox.create()` to create a new sandbox.
|
|
50
|
+
|
|
51
|
+
Example:
|
|
52
|
+
```python
|
|
53
|
+
from e2b_code_interpreter import AsyncSandbox
|
|
54
|
+
sandbox = await AsyncSandbox.create()
|
|
55
|
+
```
|
|
56
|
+
"""
|
|
57
|
+
|
|
36
58
|
default_template = DEFAULT_TEMPLATE
|
|
37
59
|
|
|
38
60
|
def __init__(self, sandbox_id: str, connection_config: ConnectionConfig):
|
|
@@ -50,55 +72,118 @@ class AsyncSandbox(BaseAsyncSandbox):
|
|
|
50
72
|
async def run_code(
|
|
51
73
|
self,
|
|
52
74
|
code: str,
|
|
53
|
-
language:
|
|
75
|
+
language: Union[Literal["python"], None] = None,
|
|
54
76
|
on_stdout: Optional[OutputHandler[OutputMessage]] = None,
|
|
55
77
|
on_stderr: Optional[OutputHandler[OutputMessage]] = None,
|
|
56
78
|
on_result: Optional[OutputHandler[Result]] = None,
|
|
79
|
+
on_error: Optional[OutputHandler[ExecutionError]] = None,
|
|
57
80
|
envs: Optional[Dict[str, str]] = None,
|
|
58
81
|
timeout: Optional[float] = None,
|
|
59
82
|
request_timeout: Optional[float] = None,
|
|
60
|
-
) -> Execution:
|
|
83
|
+
) -> Execution:
|
|
84
|
+
"""
|
|
85
|
+
Runs the code as Python.
|
|
86
|
+
|
|
87
|
+
Specify the `language` or `context` option to run the code as a different language or in a different `Context`.
|
|
88
|
+
|
|
89
|
+
You can reference previously defined variables, imports, and functions in the code.
|
|
90
|
+
|
|
91
|
+
:param code: Code to execute
|
|
92
|
+
:param language: Language to use for code execution. If not defined, the default Python context is used.
|
|
93
|
+
:param on_stdout: Callback for stdout messages
|
|
94
|
+
:param on_stderr: Callback for stderr messages
|
|
95
|
+
:param on_result: Callback for the `Result` object
|
|
96
|
+
:param on_error: Callback for the `ExecutionError` object
|
|
97
|
+
:param envs: Custom environment variables
|
|
98
|
+
:param timeout: Timeout for the code execution in **seconds**
|
|
99
|
+
:param request_timeout: Timeout for the request in **seconds**
|
|
100
|
+
|
|
101
|
+
:return: `Execution` result object
|
|
102
|
+
"""
|
|
103
|
+
...
|
|
61
104
|
|
|
62
105
|
@overload
|
|
63
106
|
async def run_code(
|
|
64
107
|
self,
|
|
65
108
|
code: str,
|
|
66
|
-
|
|
109
|
+
language: Optional[str] = None,
|
|
67
110
|
on_stdout: Optional[OutputHandler[OutputMessage]] = None,
|
|
68
111
|
on_stderr: Optional[OutputHandler[OutputMessage]] = None,
|
|
69
112
|
on_result: Optional[OutputHandler[Result]] = None,
|
|
113
|
+
on_error: Optional[OutputHandler[ExecutionError]] = None,
|
|
70
114
|
envs: Optional[Dict[str, str]] = None,
|
|
71
115
|
timeout: Optional[float] = None,
|
|
72
116
|
request_timeout: Optional[float] = None,
|
|
73
|
-
) -> Execution:
|
|
117
|
+
) -> Execution:
|
|
118
|
+
"""
|
|
119
|
+
Runs the code for the specified language.
|
|
120
|
+
|
|
121
|
+
Specify the `language` or `context` option to run the code as a different language or in a different `Context`.
|
|
122
|
+
If no language is specified, Python is used.
|
|
123
|
+
|
|
124
|
+
You can reference previously defined variables, imports, and functions in the code.
|
|
125
|
+
|
|
126
|
+
:param code: Code to execute
|
|
127
|
+
:param language: Language to use for code execution. If not defined, the default Python context is used.
|
|
128
|
+
:param on_stdout: Callback for stdout messages
|
|
129
|
+
:param on_stderr: Callback for stderr messages
|
|
130
|
+
:param on_result: Callback for the `Result` object
|
|
131
|
+
:param on_error: Callback for the `ExecutionError` object
|
|
132
|
+
:param envs: Custom environment variables
|
|
133
|
+
:param timeout: Timeout for the code execution in **seconds**
|
|
134
|
+
:param request_timeout: Timeout for the request in **seconds**
|
|
74
135
|
|
|
136
|
+
:return: `Execution` result object
|
|
137
|
+
"""
|
|
138
|
+
...
|
|
139
|
+
|
|
140
|
+
@overload
|
|
75
141
|
async def run_code(
|
|
76
142
|
self,
|
|
77
143
|
code: str,
|
|
78
|
-
language: Optional[str] = None,
|
|
79
144
|
context: Optional[Context] = None,
|
|
80
145
|
on_stdout: Optional[OutputHandler[OutputMessage]] = None,
|
|
81
146
|
on_stderr: Optional[OutputHandler[OutputMessage]] = None,
|
|
82
147
|
on_result: Optional[OutputHandler[Result]] = None,
|
|
148
|
+
on_error: Optional[OutputHandler[ExecutionError]] = None,
|
|
83
149
|
envs: Optional[Dict[str, str]] = None,
|
|
84
150
|
timeout: Optional[float] = None,
|
|
85
151
|
request_timeout: Optional[float] = None,
|
|
86
152
|
) -> Execution:
|
|
87
153
|
"""
|
|
88
|
-
Runs the code in the specified
|
|
154
|
+
Runs the code in the specified context, if not specified, the default context is used.
|
|
155
|
+
|
|
156
|
+
Specify the `language` or `context` option to run the code as a different language or in a different `Context`.
|
|
157
|
+
|
|
89
158
|
You can reference previously defined variables, imports, and functions in the code.
|
|
90
159
|
|
|
91
|
-
:param code:
|
|
92
|
-
:param
|
|
93
|
-
:param context Concrete context to run the code in. If not specified, the default context for the language is used. It's mutually exclusive with the language.
|
|
160
|
+
:param code: Code to execute
|
|
161
|
+
:param context: Concrete context to run the code in. If not specified, the default context for the language is used. It's mutually exclusive with the language.
|
|
94
162
|
:param on_stdout: Callback for stdout messages
|
|
95
163
|
:param on_stderr: Callback for stderr messages
|
|
96
164
|
:param on_result: Callback for the `Result` object
|
|
97
|
-
:param
|
|
98
|
-
:param
|
|
99
|
-
:param
|
|
100
|
-
:
|
|
165
|
+
:param on_error: Callback for the `ExecutionError` object
|
|
166
|
+
:param envs: Custom environment variables
|
|
167
|
+
:param timeout: Timeout for the code execution in **seconds**
|
|
168
|
+
:param request_timeout: Timeout for the request in **seconds**
|
|
169
|
+
|
|
170
|
+
:return: `Execution` result object
|
|
101
171
|
"""
|
|
172
|
+
...
|
|
173
|
+
|
|
174
|
+
async def run_code(
|
|
175
|
+
self,
|
|
176
|
+
code: str,
|
|
177
|
+
language: Optional[str] = None,
|
|
178
|
+
context: Optional[Context] = None,
|
|
179
|
+
on_stdout: Optional[OutputHandler[OutputMessage]] = None,
|
|
180
|
+
on_stderr: Optional[OutputHandler[OutputMessage]] = None,
|
|
181
|
+
on_result: Optional[OutputHandler[Result]] = None,
|
|
182
|
+
on_error: Optional[OutputHandler[ExecutionError]] = None,
|
|
183
|
+
envs: Optional[Dict[str, str]] = None,
|
|
184
|
+
timeout: Optional[float] = None,
|
|
185
|
+
request_timeout: Optional[float] = None,
|
|
186
|
+
) -> Execution:
|
|
102
187
|
logger.debug(f"Executing code {code}")
|
|
103
188
|
|
|
104
189
|
if context and language:
|
|
@@ -136,6 +221,7 @@ class AsyncSandbox(BaseAsyncSandbox):
|
|
|
136
221
|
on_stdout=on_stdout,
|
|
137
222
|
on_stderr=on_stderr,
|
|
138
223
|
on_result=on_result,
|
|
224
|
+
on_error=on_error,
|
|
139
225
|
)
|
|
140
226
|
|
|
141
227
|
return execution
|
|
@@ -148,17 +234,16 @@ class AsyncSandbox(BaseAsyncSandbox):
|
|
|
148
234
|
self,
|
|
149
235
|
cwd: Optional[str] = None,
|
|
150
236
|
language: Optional[str] = None,
|
|
151
|
-
envs: Optional[Dict[str, str]] = None,
|
|
152
237
|
request_timeout: Optional[float] = None,
|
|
153
238
|
) -> Context:
|
|
154
239
|
"""
|
|
155
240
|
Creates a new context to run code in.
|
|
156
241
|
|
|
157
|
-
:param cwd: Set the current working directory for the context
|
|
158
|
-
:param language: Language of the context. If not specified,
|
|
159
|
-
:param
|
|
160
|
-
|
|
161
|
-
:return: Context
|
|
242
|
+
:param cwd: Set the current working directory for the context, defaults to `/home/user`
|
|
243
|
+
:param language: Language of the context. If not specified, defaults to Python
|
|
244
|
+
:param request_timeout: Timeout for the request in **milliseconds**
|
|
245
|
+
|
|
246
|
+
:return: Context object
|
|
162
247
|
"""
|
|
163
248
|
logger.debug(f"Creating new {language} context")
|
|
164
249
|
|
|
@@ -167,8 +252,6 @@ class AsyncSandbox(BaseAsyncSandbox):
|
|
|
167
252
|
data["language"] = language
|
|
168
253
|
if cwd:
|
|
169
254
|
data["cwd"] = cwd
|
|
170
|
-
if envs:
|
|
171
|
-
data["env_vars"] = envs
|
|
172
255
|
|
|
173
256
|
try:
|
|
174
257
|
response = await self._client.post(
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import logging
|
|
2
2
|
import httpx
|
|
3
3
|
|
|
4
|
-
from typing import Optional, Dict, overload
|
|
4
|
+
from typing import Optional, Dict, overload, Literal, Union
|
|
5
5
|
from httpx import Client
|
|
6
6
|
from e2b import Sandbox as BaseSandbox, InvalidArgumentException
|
|
7
7
|
|
|
@@ -11,6 +11,7 @@ from e2b_code_interpreter.constants import (
|
|
|
11
11
|
DEFAULT_TIMEOUT,
|
|
12
12
|
)
|
|
13
13
|
from e2b_code_interpreter.models import (
|
|
14
|
+
ExecutionError,
|
|
14
15
|
Execution,
|
|
15
16
|
Context,
|
|
16
17
|
Result,
|
|
@@ -28,6 +29,28 @@ logger = logging.getLogger(__name__)
|
|
|
28
29
|
|
|
29
30
|
|
|
30
31
|
class Sandbox(BaseSandbox):
|
|
32
|
+
"""
|
|
33
|
+
E2B cloud sandbox is a secure and isolated cloud environment.
|
|
34
|
+
|
|
35
|
+
The sandbox allows you to:
|
|
36
|
+
- Access Linux OS
|
|
37
|
+
- Create, list, and delete files and directories
|
|
38
|
+
- Run commands
|
|
39
|
+
- Run isolated code
|
|
40
|
+
- Access the internet
|
|
41
|
+
|
|
42
|
+
Check docs [here](https://e2b.dev/docs).
|
|
43
|
+
|
|
44
|
+
Use the `Sandbox()` to create a new sandbox.
|
|
45
|
+
|
|
46
|
+
Example:
|
|
47
|
+
```python
|
|
48
|
+
from e2b_code_interpreter import Sandbox
|
|
49
|
+
|
|
50
|
+
sandbox = Sandbox()
|
|
51
|
+
```
|
|
52
|
+
"""
|
|
53
|
+
|
|
31
54
|
default_template = DEFAULT_TEMPLATE
|
|
32
55
|
|
|
33
56
|
@property
|
|
@@ -42,56 +65,118 @@ class Sandbox(BaseSandbox):
|
|
|
42
65
|
def run_code(
|
|
43
66
|
self,
|
|
44
67
|
code: str,
|
|
45
|
-
language:
|
|
68
|
+
language: Union[Literal["python"], None] = None,
|
|
46
69
|
on_stdout: Optional[OutputHandler[OutputMessage]] = None,
|
|
47
70
|
on_stderr: Optional[OutputHandler[OutputMessage]] = None,
|
|
48
71
|
on_result: Optional[OutputHandler[Result]] = None,
|
|
72
|
+
on_error: Optional[OutputHandler[ExecutionError]] = None,
|
|
49
73
|
envs: Optional[Dict[str, str]] = None,
|
|
50
74
|
timeout: Optional[float] = None,
|
|
51
75
|
request_timeout: Optional[float] = None,
|
|
52
|
-
) -> Execution:
|
|
76
|
+
) -> Execution:
|
|
77
|
+
"""
|
|
78
|
+
Runs the code as Python.
|
|
79
|
+
|
|
80
|
+
Specify the `language` or `context` option to run the code as a different language or in a different `Context`.
|
|
81
|
+
|
|
82
|
+
You can reference previously defined variables, imports, and functions in the code.
|
|
83
|
+
|
|
84
|
+
:param code: Code to execute
|
|
85
|
+
:param language: Language to use for code execution. If not defined, the default Python context is used.
|
|
86
|
+
:param on_stdout: Callback for stdout messages
|
|
87
|
+
:param on_stderr: Callback for stderr messages
|
|
88
|
+
:param on_result: Callback for the `Result` object
|
|
89
|
+
:param on_error: Callback for the `ExecutionError` object
|
|
90
|
+
:param envs: Custom environment variables
|
|
91
|
+
:param timeout: Timeout for the code execution in **seconds**
|
|
92
|
+
:param request_timeout: Timeout for the request in **seconds**
|
|
93
|
+
|
|
94
|
+
:return: `Execution` result object
|
|
95
|
+
"""
|
|
96
|
+
...
|
|
53
97
|
|
|
54
98
|
@overload
|
|
55
99
|
def run_code(
|
|
56
100
|
self,
|
|
57
101
|
code: str,
|
|
58
|
-
|
|
102
|
+
language: Optional[str] = None,
|
|
59
103
|
on_stdout: Optional[OutputHandler[OutputMessage]] = None,
|
|
60
104
|
on_stderr: Optional[OutputHandler[OutputMessage]] = None,
|
|
61
105
|
on_result: Optional[OutputHandler[Result]] = None,
|
|
106
|
+
on_error: Optional[OutputHandler[ExecutionError]] = None,
|
|
62
107
|
envs: Optional[Dict[str, str]] = None,
|
|
63
108
|
timeout: Optional[float] = None,
|
|
64
109
|
request_timeout: Optional[float] = None,
|
|
65
|
-
) -> Execution:
|
|
110
|
+
) -> Execution:
|
|
111
|
+
"""
|
|
112
|
+
Runs the code for the specified language.
|
|
113
|
+
|
|
114
|
+
Specify the `language` or `context` option to run the code as a different language or in a different `Context`.
|
|
115
|
+
If no language is specified, Python is used.
|
|
116
|
+
|
|
117
|
+
You can reference previously defined variables, imports, and functions in the code.
|
|
66
118
|
|
|
119
|
+
:param code: Code to execute
|
|
120
|
+
:param language: Language to use for code execution. If not defined, the default Python context is used.
|
|
121
|
+
:param on_stdout: Callback for stdout messages
|
|
122
|
+
:param on_stderr: Callback for stderr messages
|
|
123
|
+
:param on_result: Callback for the `Result` object
|
|
124
|
+
:param on_error: Callback for the `ExecutionError` object
|
|
125
|
+
:param envs: Custom environment variables
|
|
126
|
+
:param timeout: Timeout for the code execution in **seconds**
|
|
127
|
+
:param request_timeout: Timeout for the request in **seconds**
|
|
128
|
+
|
|
129
|
+
:return: `Execution` result object
|
|
130
|
+
"""
|
|
131
|
+
...
|
|
132
|
+
|
|
133
|
+
@overload
|
|
67
134
|
def run_code(
|
|
68
135
|
self,
|
|
69
136
|
code: str,
|
|
70
|
-
language: Optional[str] = None,
|
|
71
137
|
context: Optional[Context] = None,
|
|
72
138
|
on_stdout: Optional[OutputHandler[OutputMessage]] = None,
|
|
73
139
|
on_stderr: Optional[OutputHandler[OutputMessage]] = None,
|
|
74
140
|
on_result: Optional[OutputHandler[Result]] = None,
|
|
141
|
+
on_error: Optional[OutputHandler[ExecutionError]] = None,
|
|
75
142
|
envs: Optional[Dict[str, str]] = None,
|
|
76
143
|
timeout: Optional[float] = None,
|
|
77
144
|
request_timeout: Optional[float] = None,
|
|
78
145
|
) -> Execution:
|
|
79
146
|
"""
|
|
80
|
-
Runs the code in the specified
|
|
147
|
+
Runs the code in the specified context, if not specified, the default context is used.
|
|
148
|
+
|
|
149
|
+
Specify the `language` or `context` option to run the code as a different language or in a different `Context`.
|
|
150
|
+
|
|
81
151
|
You can reference previously defined variables, imports, and functions in the code.
|
|
82
152
|
|
|
83
|
-
:param code:
|
|
84
|
-
:param
|
|
85
|
-
:param context Concrete context to run the code in. If not specified, the default context for the language is used. It's mutually exclusive with the language.
|
|
153
|
+
:param code: Code to execute
|
|
154
|
+
:param context: Concrete context to run the code in. If not specified, the default context for the language is used. It's mutually exclusive with the language.
|
|
86
155
|
:param on_stdout: Callback for stdout messages
|
|
87
156
|
:param on_stderr: Callback for stderr messages
|
|
88
157
|
:param on_result: Callback for the `Result` object
|
|
89
|
-
:param
|
|
90
|
-
:param
|
|
91
|
-
:param
|
|
92
|
-
:
|
|
158
|
+
:param on_error: Callback for the `ExecutionError` object
|
|
159
|
+
:param envs: Custom environment variables
|
|
160
|
+
:param timeout: Timeout for the code execution in **seconds**
|
|
161
|
+
:param request_timeout: Timeout for the request in **seconds**
|
|
162
|
+
|
|
163
|
+
:return: `Execution` result object
|
|
93
164
|
"""
|
|
165
|
+
...
|
|
94
166
|
|
|
167
|
+
def run_code(
|
|
168
|
+
self,
|
|
169
|
+
code: str,
|
|
170
|
+
language: Optional[str] = None,
|
|
171
|
+
context: Optional[Context] = None,
|
|
172
|
+
on_stdout: Optional[OutputHandler[OutputMessage]] = None,
|
|
173
|
+
on_stderr: Optional[OutputHandler[OutputMessage]] = None,
|
|
174
|
+
on_result: Optional[OutputHandler[Result]] = None,
|
|
175
|
+
on_error: Optional[OutputHandler[ExecutionError]] = None,
|
|
176
|
+
envs: Optional[Dict[str, str]] = None,
|
|
177
|
+
timeout: Optional[float] = None,
|
|
178
|
+
request_timeout: Optional[float] = None,
|
|
179
|
+
) -> Execution:
|
|
95
180
|
logger.debug(f"Executing code {code}")
|
|
96
181
|
|
|
97
182
|
if language and context:
|
|
@@ -128,6 +213,7 @@ class Sandbox(BaseSandbox):
|
|
|
128
213
|
on_stdout=on_stdout,
|
|
129
214
|
on_stderr=on_stderr,
|
|
130
215
|
on_result=on_result,
|
|
216
|
+
on_error=on_error,
|
|
131
217
|
)
|
|
132
218
|
|
|
133
219
|
return execution
|
|
@@ -140,17 +226,16 @@ class Sandbox(BaseSandbox):
|
|
|
140
226
|
self,
|
|
141
227
|
cwd: Optional[str] = None,
|
|
142
228
|
language: Optional[str] = None,
|
|
143
|
-
envs: Optional[Dict[str, str]] = None,
|
|
144
229
|
request_timeout: Optional[float] = None,
|
|
145
230
|
) -> Context:
|
|
146
231
|
"""
|
|
147
232
|
Creates a new context to run code in.
|
|
148
233
|
|
|
149
|
-
:param cwd: Set the current working directory for the context
|
|
150
|
-
:param language: Language of the context. If not specified,
|
|
151
|
-
:param
|
|
152
|
-
|
|
153
|
-
:return: Context
|
|
234
|
+
:param cwd: Set the current working directory for the context, defaults to `/home/user`
|
|
235
|
+
:param language: Language of the context. If not specified, defaults to Python
|
|
236
|
+
:param request_timeout: Timeout for the request in **milliseconds**
|
|
237
|
+
|
|
238
|
+
:return: Context object
|
|
154
239
|
"""
|
|
155
240
|
logger.debug(f"Creating new {language} context")
|
|
156
241
|
|
|
@@ -159,8 +244,6 @@ class Sandbox(BaseSandbox):
|
|
|
159
244
|
data["language"] = language
|
|
160
245
|
if cwd:
|
|
161
246
|
data["cwd"] = cwd
|
|
162
|
-
if envs:
|
|
163
|
-
data["env_vars"] = envs
|
|
164
247
|
|
|
165
248
|
try:
|
|
166
249
|
response = self._client.post(
|
{e2b_code_interpreter-0.0.11b47 → e2b_code_interpreter-1.0.0}/e2b_code_interpreter/models.py
RENAMED
|
@@ -17,7 +17,7 @@ from typing import (
|
|
|
17
17
|
|
|
18
18
|
from httpx import Response
|
|
19
19
|
|
|
20
|
-
from .
|
|
20
|
+
from .charts import Chart, _deserialize_chart
|
|
21
21
|
|
|
22
22
|
T = TypeVar("T")
|
|
23
23
|
OutputHandler = Union[
|
|
@@ -30,12 +30,22 @@ logger = logging.getLogger(__name__)
|
|
|
30
30
|
|
|
31
31
|
@dataclass
|
|
32
32
|
class OutputMessage:
|
|
33
|
+
"""
|
|
34
|
+
Represents an output message from the sandbox code execution.
|
|
35
|
+
"""
|
|
36
|
+
|
|
33
37
|
line: str
|
|
38
|
+
"""
|
|
39
|
+
The output line.
|
|
40
|
+
"""
|
|
34
41
|
timestamp: int
|
|
35
42
|
"""
|
|
36
43
|
Unix epoch in nanoseconds
|
|
37
44
|
"""
|
|
38
45
|
error: bool = False
|
|
46
|
+
"""
|
|
47
|
+
Whether the output is an error.
|
|
48
|
+
"""
|
|
39
49
|
|
|
40
50
|
def __str__(self):
|
|
41
51
|
return self.line
|
|
@@ -49,8 +59,17 @@ class ExecutionError:
|
|
|
49
59
|
"""
|
|
50
60
|
|
|
51
61
|
name: str
|
|
62
|
+
"""
|
|
63
|
+
Name of the error.
|
|
64
|
+
"""
|
|
52
65
|
value: str
|
|
66
|
+
"""
|
|
67
|
+
Value of the error.
|
|
68
|
+
"""
|
|
53
69
|
traceback: str
|
|
70
|
+
"""
|
|
71
|
+
The raw traceback of the error.
|
|
72
|
+
"""
|
|
54
73
|
|
|
55
74
|
def __init__(self, name: str, value: str, traceback: str, **kwargs):
|
|
56
75
|
self.name = name
|
|
@@ -96,7 +115,7 @@ class Result:
|
|
|
96
115
|
json: Optional[dict] = None
|
|
97
116
|
javascript: Optional[str] = None
|
|
98
117
|
data: Optional[dict] = None
|
|
99
|
-
|
|
118
|
+
chart: Optional[Chart] = None
|
|
100
119
|
is_main_result: bool = False
|
|
101
120
|
"""Whether this data is the result of the cell. Data can be produced by display calls of which can be multiple in a cell."""
|
|
102
121
|
extra: Optional[dict] = None
|
|
@@ -115,7 +134,7 @@ class Result:
|
|
|
115
134
|
json: Optional[dict] = None,
|
|
116
135
|
javascript: Optional[str] = None,
|
|
117
136
|
data: Optional[dict] = None,
|
|
118
|
-
|
|
137
|
+
chart: Optional[dict] = None,
|
|
119
138
|
is_main_result: bool = False,
|
|
120
139
|
extra: Optional[dict] = None,
|
|
121
140
|
**kwargs, # Allows for future expansion
|
|
@@ -131,12 +150,12 @@ class Result:
|
|
|
131
150
|
self.json = json
|
|
132
151
|
self.javascript = javascript
|
|
133
152
|
self.data = data
|
|
134
|
-
if
|
|
153
|
+
if chart:
|
|
135
154
|
try:
|
|
136
|
-
self.
|
|
155
|
+
self.chart = _deserialize_chart(chart)
|
|
137
156
|
except Exception as e:
|
|
138
157
|
logger.error(
|
|
139
|
-
f"Error deserializing
|
|
158
|
+
f"Error deserializing chart, check if you are using the latest version of the library: {e}"
|
|
140
159
|
)
|
|
141
160
|
self.is_main_result = is_main_result
|
|
142
161
|
self.extra = extra
|
|
@@ -170,8 +189,8 @@ class Result:
|
|
|
170
189
|
formats.append("javascript")
|
|
171
190
|
if self.data:
|
|
172
191
|
formats.append("data")
|
|
173
|
-
if self.
|
|
174
|
-
formats.append("
|
|
192
|
+
if self.chart:
|
|
193
|
+
formats.append("chart")
|
|
175
194
|
|
|
176
195
|
if self.extra:
|
|
177
196
|
for key in self.extra:
|
|
@@ -394,6 +413,7 @@ def parse_output(
|
|
|
394
413
|
on_stdout: Optional[OutputHandler[OutputMessage]] = None,
|
|
395
414
|
on_stderr: Optional[OutputHandler[OutputMessage]] = None,
|
|
396
415
|
on_result: Optional[OutputHandler[Result]] = None,
|
|
416
|
+
on_error: Optional[OutputHandler[ExecutionError]] = None,
|
|
397
417
|
):
|
|
398
418
|
data = json.loads(output)
|
|
399
419
|
data_type = data.pop("type")
|
|
@@ -413,15 +433,30 @@ def parse_output(
|
|
|
413
433
|
on_stderr(OutputMessage(data["text"], data["timestamp"], True))
|
|
414
434
|
elif data_type == "error":
|
|
415
435
|
execution.error = ExecutionError(data["name"], data["value"], data["traceback"])
|
|
436
|
+
if on_error:
|
|
437
|
+
on_error(execution.error)
|
|
416
438
|
elif data_type == "number_of_executions":
|
|
417
439
|
execution.execution_count = data["execution_count"]
|
|
418
440
|
|
|
419
441
|
|
|
420
442
|
@dataclass
|
|
421
443
|
class Context:
|
|
444
|
+
"""
|
|
445
|
+
Represents a context for code execution.
|
|
446
|
+
"""
|
|
447
|
+
|
|
422
448
|
id: str
|
|
449
|
+
"""
|
|
450
|
+
The ID of the context.
|
|
451
|
+
"""
|
|
423
452
|
language: str
|
|
453
|
+
"""
|
|
454
|
+
The language of the context.
|
|
455
|
+
"""
|
|
424
456
|
cwd: str
|
|
457
|
+
"""
|
|
458
|
+
The working directory of the context.
|
|
459
|
+
"""
|
|
425
460
|
|
|
426
461
|
def __init__(self, context_id: str, language: str, cwd: str, **kwargs):
|
|
427
462
|
self.id = context_id
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[tool.poetry]
|
|
2
2
|
name = "e2b-code-interpreter"
|
|
3
|
-
version = "0.0
|
|
3
|
+
version = "1.0.0"
|
|
4
4
|
description = "E2B Code Interpreter - Stateful code execution"
|
|
5
5
|
authors = ["e2b <hello@e2b.dev>"]
|
|
6
6
|
license = "Apache-2.0"
|
|
@@ -14,7 +14,7 @@ python = "^3.8"
|
|
|
14
14
|
|
|
15
15
|
httpx = ">=0.20.0,<0.28.0"
|
|
16
16
|
attrs = ">=21.3.0"
|
|
17
|
-
e2b = "^0.
|
|
17
|
+
e2b = "^1.0.0"
|
|
18
18
|
|
|
19
19
|
[tool.poetry.group.dev.dependencies]
|
|
20
20
|
black = "^24.3.0"
|
|
@@ -1,90 +0,0 @@
|
|
|
1
|
-
# Code interpreter extension for Python
|
|
2
|
-
|
|
3
|
-
The repository contains a template and modules for the code interpreter sandbox. It is based on the Jupyter server and implements the Jupyter Kernel messaging protocol. This allows for sharing context between code executions and improves support for plotting charts and other display-able data.
|
|
4
|
-
|
|
5
|
-
## Key Features
|
|
6
|
-
|
|
7
|
-
- **Stateful Execution**: Unlike traditional sandboxes that treat each code execution independently, this package maintains context across executions.
|
|
8
|
-
- **Displaying Graph & Data**: Implements parts of the [Jupyter Kernel messaging protocol](https://jupyter-client.readthedocs.io/en/latest/messaging.html), which support for interactive features like plotting charts, rendering DataFrames, etc.
|
|
9
|
-
|
|
10
|
-
## Installation
|
|
11
|
-
|
|
12
|
-
```sh
|
|
13
|
-
pip install e2b-code-interpreter
|
|
14
|
-
```
|
|
15
|
-
|
|
16
|
-
## Examples
|
|
17
|
-
|
|
18
|
-
### Minimal example with the sharing context
|
|
19
|
-
|
|
20
|
-
```python
|
|
21
|
-
from e2b_code_interpreter import Sandbox
|
|
22
|
-
|
|
23
|
-
with Sandbox() as sandbox:
|
|
24
|
-
sandbox.run_code("x = 1")
|
|
25
|
-
|
|
26
|
-
execution = sandbox.run_code("x+=1; x")
|
|
27
|
-
print(execution.text) # outputs 2
|
|
28
|
-
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
### Get charts and any display-able data
|
|
32
|
-
|
|
33
|
-
```python
|
|
34
|
-
import base64
|
|
35
|
-
import io
|
|
36
|
-
|
|
37
|
-
from matplotlib import image as mpimg, pyplot as plt
|
|
38
|
-
|
|
39
|
-
from e2b_code_interpreter import Sandbox
|
|
40
|
-
|
|
41
|
-
code = """
|
|
42
|
-
import matplotlib.pyplot as plt
|
|
43
|
-
import numpy as np
|
|
44
|
-
|
|
45
|
-
x = np.linspace(0, 20, 100)
|
|
46
|
-
y = np.sin(x)
|
|
47
|
-
|
|
48
|
-
plt.plot(x, y)
|
|
49
|
-
plt.show()
|
|
50
|
-
"""
|
|
51
|
-
|
|
52
|
-
with Sandbox() as sandbox:
|
|
53
|
-
# you can install dependencies in "jupyter notebook style"
|
|
54
|
-
sandbox.run_code("!pip install matplotlib")
|
|
55
|
-
|
|
56
|
-
# plot random graph
|
|
57
|
-
execution = sandbox.run_code(code)
|
|
58
|
-
|
|
59
|
-
# there's your image
|
|
60
|
-
image = execution.results[0].png
|
|
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')
|
|
66
|
-
|
|
67
|
-
plt.imshow(i, interpolation='nearest')
|
|
68
|
-
plt.show()
|
|
69
|
-
```
|
|
70
|
-
|
|
71
|
-
### Streaming code output
|
|
72
|
-
|
|
73
|
-
```python
|
|
74
|
-
from e2b_code_interpreter import Sandbox
|
|
75
|
-
|
|
76
|
-
code = """
|
|
77
|
-
import time
|
|
78
|
-
import pandas as pd
|
|
79
|
-
|
|
80
|
-
print("hello")
|
|
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)
|
|
85
|
-
print("world")
|
|
86
|
-
"""
|
|
87
|
-
|
|
88
|
-
with Sandbox() as sandbox:
|
|
89
|
-
sandbox.run_code(code, on_stdout=print, on_stderr=print, on_result=(lambda result: print(result.text)))
|
|
90
|
-
```
|
{e2b_code_interpreter-0.0.11b47 → e2b_code_interpreter-1.0.0}/e2b_code_interpreter/__init__.py
RENAMED
|
File without changes
|
{e2b_code_interpreter-0.0.11b47 → e2b_code_interpreter-1.0.0}/e2b_code_interpreter/exceptions.py
RENAMED
|
File without changes
|