e2b-code-interpreter 0.0.11b47__tar.gz → 1.0.1__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.
@@ -0,0 +1,73 @@
1
+ Metadata-Version: 2.1
2
+ Name: e2b-code-interpreter
3
+ Version: 1.0.1
4
+ Summary: E2B Code Interpreter - Stateful code execution
5
+ Home-page: https://e2b.dev/
6
+ License: Apache-2.0
7
+ Author: e2b
8
+ Author-email: hello@e2b.dev
9
+ Requires-Python: >=3.8,<4.0
10
+ Classifier: License :: OSI Approved :: Apache Software License
11
+ Classifier: Programming Language :: Python :: 3
12
+ Classifier: Programming Language :: Python :: 3.8
13
+ Classifier: Programming Language :: Python :: 3.9
14
+ Classifier: Programming Language :: Python :: 3.10
15
+ Classifier: Programming Language :: Python :: 3.11
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Requires-Dist: attrs (>=21.3.0)
18
+ Requires-Dist: e2b (>=1.0.0,<2.0.0)
19
+ Requires-Dist: httpx (>=0.20.0,<0.28.0)
20
+ Project-URL: Bug Tracker, https://github.com/e2b-dev/code-interpreter/issues
21
+ Project-URL: Repository, https://github.com/e2b-dev/e2b-code-interpreter/tree/python
22
+ Description-Content-Type: text/markdown
23
+
24
+ <p align="center">
25
+ <img width="100" src="https://raw.githubusercontent.com/e2b-dev/E2B/refs/heads/main/readme-assets/logo-circle.png" alt="e2b logo">
26
+ </p>
27
+
28
+ <h4 align="center">
29
+ <a href="https://pypi.org/project/e2b/">
30
+ <img alt="Last 1 month downloads for the Python SDK" loading="lazy" width="200" height="20" decoding="async" data-nimg="1"
31
+ style="color:transparent;width:auto;height:100%" src="https://img.shields.io/pypi/dm/e2b?label=PyPI%20Downloads">
32
+ </a>
33
+ </h4>
34
+
35
+ <!---
36
+ <img width="100%" src="/readme-assets/preview.png" alt="Cover image">
37
+ --->
38
+ ## What is E2B?
39
+ [E2B](https://www.e2b.dev/) is an open-source infrastructure that allows you run to AI-generated code in secure isolated sandboxes in the cloud. To start and control sandboxes, use our [JavaScript SDK](https://www.npmjs.com/package/@e2b/code-interpreter) or [Python SDK](https://pypi.org/project/e2b_code_interpreter).
40
+
41
+ ## Run your first Sandbox
42
+
43
+ ### 1. Install SDK
44
+
45
+ ```
46
+ pip install e2b-code-interpreter
47
+ ```
48
+
49
+ ### 2. Get your E2B API key
50
+ 1. Sign up to E2B [here](https://e2b.dev).
51
+ 2. Get your API key [here](https://e2b.dev/dashboard?tab=keys).
52
+ 3. Set environment variable with your API key.
53
+ ```
54
+ E2B_API_KEY=e2b_***
55
+ ```
56
+
57
+ ### 3. Execute code with code interpreter inside Sandbox
58
+
59
+ ```py
60
+ from e2b_code_interpreter import Sandbox
61
+
62
+ with Sandbox() as sandbox:
63
+ sandbox.run_code("x = 1")
64
+ execution = sandbox.run_code("x+=1; x")
65
+ print(execution.text) # outputs 2
66
+ ```
67
+
68
+ ### 4. Check docs
69
+ Visit [E2B documentation](https://e2b.dev/docs).
70
+
71
+ ### 5. E2B cookbook
72
+ Visit our [Cookbook](https://github.com/e2b-dev/e2b-cookbook/tree/main) to get inspired by examples with different LLMs and AI frameworks.
73
+
@@ -0,0 +1,49 @@
1
+ <p align="center">
2
+ <img width="100" src="https://raw.githubusercontent.com/e2b-dev/E2B/refs/heads/main/readme-assets/logo-circle.png" alt="e2b logo">
3
+ </p>
4
+
5
+ <h4 align="center">
6
+ <a href="https://pypi.org/project/e2b/">
7
+ <img alt="Last 1 month downloads for the Python SDK" loading="lazy" width="200" height="20" decoding="async" data-nimg="1"
8
+ style="color:transparent;width:auto;height:100%" src="https://img.shields.io/pypi/dm/e2b?label=PyPI%20Downloads">
9
+ </a>
10
+ </h4>
11
+
12
+ <!---
13
+ <img width="100%" src="/readme-assets/preview.png" alt="Cover image">
14
+ --->
15
+ ## What is E2B?
16
+ [E2B](https://www.e2b.dev/) is an open-source infrastructure that allows you run to AI-generated code in secure isolated sandboxes in the cloud. To start and control sandboxes, use our [JavaScript SDK](https://www.npmjs.com/package/@e2b/code-interpreter) or [Python SDK](https://pypi.org/project/e2b_code_interpreter).
17
+
18
+ ## Run your first Sandbox
19
+
20
+ ### 1. Install SDK
21
+
22
+ ```
23
+ pip install e2b-code-interpreter
24
+ ```
25
+
26
+ ### 2. Get your E2B API key
27
+ 1. Sign up to E2B [here](https://e2b.dev).
28
+ 2. Get your API key [here](https://e2b.dev/dashboard?tab=keys).
29
+ 3. Set environment variable with your API key.
30
+ ```
31
+ E2B_API_KEY=e2b_***
32
+ ```
33
+
34
+ ### 3. Execute code with code interpreter inside Sandbox
35
+
36
+ ```py
37
+ from e2b_code_interpreter import Sandbox
38
+
39
+ with Sandbox() as sandbox:
40
+ sandbox.run_code("x = 1")
41
+ execution = sandbox.run_code("x+=1; x")
42
+ print(execution.text) # outputs 2
43
+ ```
44
+
45
+ ### 4. Check docs
46
+ Visit [E2B documentation](https://e2b.dev/docs).
47
+
48
+ ### 5. E2B cookbook
49
+ Visit our [Cookbook](https://github.com/e2b-dev/e2b-cookbook/tree/main) to get inspired by examples with different LLMs and AI frameworks.
@@ -2,9 +2,9 @@ import enum
2
2
  from typing import List, Tuple, Any, Optional, Union
3
3
 
4
4
 
5
- class GraphType(str, enum.Enum):
5
+ class ChartType(str, enum.Enum):
6
6
  """
7
- Graph types
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
- SUPERGRAPH = "supergraph"
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 Graph:
36
+ class Chart:
37
37
  """
38
- Extracted data from a graph. It's useful for building an interactive graphs or custom visualizations.
38
+ Extracted data from a chart. It's useful for building an interactive charts or custom visualizations.
39
39
  """
40
40
 
41
- type: GraphType
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 = GraphType(kwargs["type"] or GraphType.UNKNOWN)
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 Graph2D(Graph):
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 PointGraph(Graph2D):
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 LineGraph(PointGraph):
112
- type = GraphType.LINE
111
+ class LineChart(PointChart):
112
+ type = ChartType.LINE
113
113
 
114
114
 
115
- class ScatterGraph(PointGraph):
116
- type = GraphType.SCATTER
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 BarGraph(Graph2D):
131
- type = GraphType.BAR
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 PieGraph(Graph):
152
- type = GraphType.PIE
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 BoxAndWhiskerGraph(Graph2D):
179
- type = GraphType.BOX_AND_WHISKER
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 SuperGraph(Graph):
189
- type = GraphType.SUPERGRAPH
188
+ class SuperChart(Chart):
189
+ type = ChartType.SUPERCHART
190
190
 
191
191
  elements: List[
192
- Union[LineGraph, ScatterGraph, BarGraph, PieGraph, BoxAndWhiskerGraph]
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 = [deserialize_graph(g) for g in kwargs["elements"]]
197
+ self.elements = [_deserialize_chart(g) for g in kwargs["elements"]]
198
198
 
199
199
 
200
- GraphTypes = Union[
201
- LineGraph, ScatterGraph, BarGraph, PieGraph, BoxAndWhiskerGraph, SuperGraph
200
+ ChartTypes = Union[
201
+ LineChart, ScatterChart, BarChart, PieChart, BoxAndWhiskerChart, SuperChart
202
202
  ]
203
203
 
204
204
 
205
- def deserialize_graph(data: Optional[dict]) -> Optional[GraphTypes]:
205
+ def _deserialize_chart(data: Optional[dict]) -> Optional[ChartTypes]:
206
206
  if not data:
207
207
  return None
208
208
 
209
- if data["type"] == GraphType.LINE:
210
- graph = LineGraph(**data)
211
- elif data["type"] == GraphType.SCATTER:
212
- graph = ScatterGraph(**data)
213
- elif data["type"] == GraphType.BAR:
214
- graph = BarGraph(**data)
215
- elif data["type"] == GraphType.PIE:
216
- graph = PieGraph(**data)
217
- elif data["type"] == GraphType.BOX_AND_WHISKER:
218
- graph = BoxAndWhiskerGraph(**data)
219
- elif data["type"] == GraphType.SUPERGRAPH:
220
- graph = SuperGraph(**data)
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
- graph = Graph(**data)
222
+ chart = Chart(**data)
223
223
 
224
- return graph
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: Optional[str] = None,
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
- context: Optional[Context] = None,
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 language/context, if not specified, the default context is used.
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: The code to execute
92
- :param language Based on the value, a default context for the language is used. If not defined and no context is provided, the default Python context is used.
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 envs: Environment variables
98
- :param timeout: Max time to wait for the execution to finish
99
- :param request_timeout: Max time to wait for the request to finish
100
- :return: Execution object
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, the default Python context is used.
159
- :param envs: Environment variables
160
- :param request_timeout: Max time to wait for the request to finish
161
- :return: Context id
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: Optional[str] = None,
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
- context: Optional[Context] = None,
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 language/context, if not specified, the default context is used.
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: The code to execute
84
- :param language Based on the value, a default context for the language is used. If not defined and no context is provided, the default Python context is used.
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 envs: Environment variables
90
- :param timeout: Max time to wait for the execution to finish
91
- :param request_timeout: Max time to wait for the request to finish
92
- :return: Execution object
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, the default Python context is used.
151
- :param envs: Environment variables
152
- :param request_timeout: Max time to wait for the request to finish
153
- :return: Context id
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(
@@ -1,3 +1,3 @@
1
- DEFAULT_TEMPLATE = "code-interpreter-beta"
1
+ DEFAULT_TEMPLATE = "code-interpreter-v1"
2
2
  JUPYTER_PORT = 49999
3
3
  DEFAULT_TIMEOUT = 300
@@ -17,7 +17,7 @@ from typing import (
17
17
 
18
18
  from httpx import Response
19
19
 
20
- from .graphs import Graph, deserialize_graph
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
- graph: Optional[Graph] = None
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
- graph: Optional[dict] = None,
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 graph:
153
+ if chart:
135
154
  try:
136
- self.graph = deserialize_graph(graph)
155
+ self.chart = _deserialize_chart(chart)
137
156
  except Exception as e:
138
157
  logger.error(
139
- f"Error deserializing graph, check if you are using the latest version of the library: {e}"
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.graph:
174
- formats.append("graph")
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.11b47"
3
+ version = "1.0.1"
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.2a50"
17
+ e2b = "^1.0.0"
18
18
 
19
19
  [tool.poetry.group.dev.dependencies]
20
20
  black = "^24.3.0"
@@ -1,114 +0,0 @@
1
- Metadata-Version: 2.1
2
- Name: e2b-code-interpreter
3
- Version: 0.0.11b47
4
- Summary: E2B Code Interpreter - Stateful code execution
5
- Home-page: https://e2b.dev/
6
- License: Apache-2.0
7
- Author: e2b
8
- Author-email: hello@e2b.dev
9
- Requires-Python: >=3.8,<4.0
10
- Classifier: License :: OSI Approved :: Apache Software License
11
- Classifier: Programming Language :: Python :: 3
12
- Classifier: Programming Language :: Python :: 3.8
13
- Classifier: Programming Language :: Python :: 3.9
14
- Classifier: Programming Language :: Python :: 3.10
15
- Classifier: Programming Language :: Python :: 3.11
16
- Classifier: Programming Language :: Python :: 3.12
17
- Requires-Dist: attrs (>=21.3.0)
18
- Requires-Dist: e2b (>=0.17.2a50,<0.18.0)
19
- Requires-Dist: httpx (>=0.20.0,<0.28.0)
20
- Project-URL: Bug Tracker, https://github.com/e2b-dev/code-interpreter/issues
21
- Project-URL: Repository, https://github.com/e2b-dev/e2b-code-interpreter/tree/python
22
- Description-Content-Type: text/markdown
23
-
24
- # Code interpreter extension for Python
25
-
26
- 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
-
28
- ## Key Features
29
-
30
- - **Stateful Execution**: Unlike traditional sandboxes that treat each code execution independently, this package maintains context across executions.
31
- - **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.
32
-
33
- ## Installation
34
-
35
- ```sh
36
- pip install e2b-code-interpreter
37
- ```
38
-
39
- ## Examples
40
-
41
- ### Minimal example with the sharing context
42
-
43
- ```python
44
- from e2b_code_interpreter import Sandbox
45
-
46
- with Sandbox() as sandbox:
47
- sandbox.run_code("x = 1")
48
-
49
- execution = sandbox.run_code("x+=1; x")
50
- print(execution.text) # outputs 2
51
-
52
- ```
53
-
54
- ### Get charts and any display-able data
55
-
56
- ```python
57
- import base64
58
- import io
59
-
60
- from matplotlib import image as mpimg, pyplot as plt
61
-
62
- from e2b_code_interpreter import Sandbox
63
-
64
- code = """
65
- import matplotlib.pyplot as plt
66
- import numpy as np
67
-
68
- x = np.linspace(0, 20, 100)
69
- y = np.sin(x)
70
-
71
- plt.plot(x, y)
72
- plt.show()
73
- """
74
-
75
- with Sandbox() as sandbox:
76
- # you can install dependencies in "jupyter notebook style"
77
- sandbox.run_code("!pip install matplotlib")
78
-
79
- # plot random graph
80
- execution = sandbox.run_code(code)
81
-
82
- # there's your image
83
- image = execution.results[0].png
84
-
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')
89
-
90
- plt.imshow(i, interpolation='nearest')
91
- plt.show()
92
- ```
93
-
94
- ### Streaming code output
95
-
96
- ```python
97
- from e2b_code_interpreter import Sandbox
98
-
99
- code = """
100
- import time
101
- import pandas as pd
102
-
103
- print("hello")
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)
108
- print("world")
109
- """
110
-
111
- with Sandbox() as sandbox:
112
- sandbox.run_code(code, on_stdout=print, on_stderr=print, on_result=(lambda result: print(result.text)))
113
- ```
114
-
@@ -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
- ```