opensandbox-code-interpreter 0.1.0__py3-none-any.whl
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.
- code_interpreter/__init__.py +45 -0
- code_interpreter/adapters/__init__.py +30 -0
- code_interpreter/adapters/code_adapter.py +268 -0
- code_interpreter/adapters/converter/__init__.py +26 -0
- code_interpreter/adapters/converter/code_execution_converter.py +108 -0
- code_interpreter/adapters/factory.py +58 -0
- code_interpreter/code_interpreter.py +343 -0
- code_interpreter/models/__init__.py +28 -0
- code_interpreter/models/code.py +67 -0
- code_interpreter/models/code_sync.py +41 -0
- code_interpreter/py.typed +0 -0
- code_interpreter/services/__init__.py +24 -0
- code_interpreter/services/code.py +149 -0
- code_interpreter/sync/__init__.py +18 -0
- code_interpreter/sync/adapters/__init__.py +26 -0
- code_interpreter/sync/adapters/code_adapter.py +215 -0
- code_interpreter/sync/adapters/factory.py +54 -0
- code_interpreter/sync/code_interpreter.py +286 -0
- code_interpreter/sync/services/__init__.py +27 -0
- code_interpreter/sync/services/code.py +122 -0
- opensandbox_code_interpreter-0.1.0.dist-info/METADATA +462 -0
- opensandbox_code_interpreter-0.1.0.dist-info/RECORD +24 -0
- opensandbox_code_interpreter-0.1.0.dist-info/WHEEL +4 -0
- opensandbox_code_interpreter-0.1.0.dist-info/licenses/LICENSE +201 -0
|
@@ -0,0 +1,343 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Copyright 2025 Alibaba Group Holding Ltd.
|
|
3
|
+
#
|
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
# you may not use this file except in compliance with the License.
|
|
6
|
+
# You may obtain a copy of the License at
|
|
7
|
+
#
|
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
#
|
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
# See the License for the specific language governing permissions and
|
|
14
|
+
# limitations under the License.
|
|
15
|
+
#
|
|
16
|
+
"""
|
|
17
|
+
Code Interpreter SDK providing secure, isolated code execution capabilities.
|
|
18
|
+
|
|
19
|
+
This module provides the main CodeInterpreter class that extends basic Sandbox
|
|
20
|
+
functionality with specialized code execution features, including multi-language
|
|
21
|
+
support, session management, and variable persistence.
|
|
22
|
+
"""
|
|
23
|
+
|
|
24
|
+
import logging
|
|
25
|
+
from datetime import datetime, timedelta, timezone
|
|
26
|
+
from uuid import UUID
|
|
27
|
+
|
|
28
|
+
from opensandbox.exceptions import (
|
|
29
|
+
InvalidArgumentException,
|
|
30
|
+
SandboxException,
|
|
31
|
+
SandboxInternalException,
|
|
32
|
+
)
|
|
33
|
+
from opensandbox.models.sandboxes import (
|
|
34
|
+
SandboxEndpoint,
|
|
35
|
+
SandboxInfo,
|
|
36
|
+
SandboxMetrics,
|
|
37
|
+
)
|
|
38
|
+
from opensandbox.sandbox import Sandbox
|
|
39
|
+
|
|
40
|
+
from code_interpreter.adapters.factory import AdapterFactory
|
|
41
|
+
from code_interpreter.services.code import Codes
|
|
42
|
+
|
|
43
|
+
logger = logging.getLogger(__name__)
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
class CodeInterpreter:
|
|
47
|
+
"""
|
|
48
|
+
Code Interpreter SDK providing secure, isolated code execution capabilities.
|
|
49
|
+
|
|
50
|
+
This class extends the basic Sandbox functionality with specialized code execution features,
|
|
51
|
+
including multi-language support, session management, and variable persistence.
|
|
52
|
+
|
|
53
|
+
Key Features:
|
|
54
|
+
|
|
55
|
+
- Multi-language Code Execution: Support for Python, JavaScript, Bash, Java, Kotlin
|
|
56
|
+
- Session Management: Persistent execution contexts with variable state
|
|
57
|
+
- Sandbox Integration: Full access to underlying sandbox file system and command execution
|
|
58
|
+
- Streaming Execution: Real-time code execution with output streaming
|
|
59
|
+
- Variable Inspection: Access to execution variables and state
|
|
60
|
+
|
|
61
|
+
Usage Example:
|
|
62
|
+
|
|
63
|
+
```python
|
|
64
|
+
# First create a sandbox instance
|
|
65
|
+
|
|
66
|
+
sandbox = await Sandbox.create(
|
|
67
|
+
"python:3.11",
|
|
68
|
+
resource={"cpu": "1", "memory": "2Gi"}
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
# Then create a code interpreter wrapping the sandbox
|
|
72
|
+
interpreter = await CodeInterpreter.create(sandbox=sandbox)
|
|
73
|
+
|
|
74
|
+
# Execute code with context
|
|
75
|
+
from code_interpreter.models.code import SupportedLanguage
|
|
76
|
+
context = await interpreter.codes.create_context(SupportedLanguage.PYTHON)
|
|
77
|
+
result = await interpreter.codes.run("print('Hello World')", context=context)
|
|
78
|
+
print(result.logs.stdout) # Output: Hello World
|
|
79
|
+
|
|
80
|
+
# Access underlying sandbox for file operations
|
|
81
|
+
await interpreter.sandbox.files.write_files([
|
|
82
|
+
WriteEntry(path="data.txt", data="Hello")
|
|
83
|
+
])
|
|
84
|
+
file_result = await interpreter.codes.run(
|
|
85
|
+
"with open('data.txt') as f: print(f.read())",
|
|
86
|
+
context=context,
|
|
87
|
+
)
|
|
88
|
+
|
|
89
|
+
# Always clean up resources
|
|
90
|
+
await interpreter.kill()
|
|
91
|
+
await interpreter.sandbox.close()
|
|
92
|
+
```
|
|
93
|
+
"""
|
|
94
|
+
|
|
95
|
+
def __init__(self, sandbox: Sandbox, code_service: Codes) -> None:
|
|
96
|
+
"""
|
|
97
|
+
Initialize CodeInterpreter with sandbox and code service.
|
|
98
|
+
|
|
99
|
+
Note: This constructor is for internal use. Use CodeInterpreter.create() instead.
|
|
100
|
+
|
|
101
|
+
Args:
|
|
102
|
+
sandbox: Underlying sandbox instance
|
|
103
|
+
code_service: Code execution implementation
|
|
104
|
+
"""
|
|
105
|
+
self._sandbox = sandbox
|
|
106
|
+
self._code_service = code_service
|
|
107
|
+
|
|
108
|
+
@property
|
|
109
|
+
def sandbox(self) -> Sandbox:
|
|
110
|
+
"""
|
|
111
|
+
Provides access to the underlying sandbox instance.
|
|
112
|
+
|
|
113
|
+
Returns:
|
|
114
|
+
The underlying sandbox instance
|
|
115
|
+
"""
|
|
116
|
+
return self._sandbox
|
|
117
|
+
|
|
118
|
+
@property
|
|
119
|
+
def id(self) -> UUID:
|
|
120
|
+
"""
|
|
121
|
+
Gets the unique identifier of this code interpreter (same as underlying sandbox ID).
|
|
122
|
+
|
|
123
|
+
Returns:
|
|
124
|
+
UUID of the code interpreter/sandbox
|
|
125
|
+
"""
|
|
126
|
+
return self._sandbox.id
|
|
127
|
+
|
|
128
|
+
@property
|
|
129
|
+
def files(self):
|
|
130
|
+
"""
|
|
131
|
+
Provides access to file system operations within the sandbox.
|
|
132
|
+
|
|
133
|
+
Allows writing, reading, listing, and deleting files and directories.
|
|
134
|
+
|
|
135
|
+
Returns:
|
|
136
|
+
Service for filesystem manipulation
|
|
137
|
+
"""
|
|
138
|
+
return self._sandbox.files
|
|
139
|
+
|
|
140
|
+
@property
|
|
141
|
+
def commands(self):
|
|
142
|
+
"""
|
|
143
|
+
Provides access to command execution operations.
|
|
144
|
+
|
|
145
|
+
Allows running shell commands, capturing output, and managing processes.
|
|
146
|
+
|
|
147
|
+
Returns:
|
|
148
|
+
Service for command execution
|
|
149
|
+
"""
|
|
150
|
+
return self._sandbox.commands
|
|
151
|
+
|
|
152
|
+
@property
|
|
153
|
+
def metrics(self):
|
|
154
|
+
"""
|
|
155
|
+
Provides access to sandbox metrics and monitoring.
|
|
156
|
+
|
|
157
|
+
Allows retrieving resource usage statistics (CPU, memory) and other performance metrics.
|
|
158
|
+
|
|
159
|
+
Returns:
|
|
160
|
+
Service for metrics retrieval
|
|
161
|
+
"""
|
|
162
|
+
return self._sandbox.metrics
|
|
163
|
+
|
|
164
|
+
@property
|
|
165
|
+
def codes(self) -> Codes:
|
|
166
|
+
"""
|
|
167
|
+
Provides access to code execution operations.
|
|
168
|
+
|
|
169
|
+
This service enables:
|
|
170
|
+
- Multi-language code execution (Python, JavaScript, Bash, etc.)
|
|
171
|
+
- Execution context management with persistent variables
|
|
172
|
+
- Real-time output streaming and interruption capabilities
|
|
173
|
+
|
|
174
|
+
Returns:
|
|
175
|
+
Service for advanced code execution with session support
|
|
176
|
+
"""
|
|
177
|
+
return self._code_service
|
|
178
|
+
|
|
179
|
+
async def get_endpoint(self, port: int) -> SandboxEndpoint:
|
|
180
|
+
"""
|
|
181
|
+
Gets a specific network endpoint for the underlying sandbox.
|
|
182
|
+
|
|
183
|
+
This allows access to specific ports exposed by the sandbox, which can be
|
|
184
|
+
useful for connecting to additional services or debugging interfaces.
|
|
185
|
+
|
|
186
|
+
Args:
|
|
187
|
+
port: The port number to get the endpoint for
|
|
188
|
+
|
|
189
|
+
Returns:
|
|
190
|
+
Endpoint information including host, port, and connection details
|
|
191
|
+
|
|
192
|
+
Raises:
|
|
193
|
+
SandboxException: If endpoint cannot be retrieved
|
|
194
|
+
"""
|
|
195
|
+
return await self._sandbox.get_endpoint(port)
|
|
196
|
+
|
|
197
|
+
async def get_info(self) -> SandboxInfo:
|
|
198
|
+
"""
|
|
199
|
+
Gets the current status of this sandbox.
|
|
200
|
+
|
|
201
|
+
Returns:
|
|
202
|
+
Current sandbox status including state and metadata
|
|
203
|
+
|
|
204
|
+
Raises:
|
|
205
|
+
SandboxException: If status cannot be retrieved
|
|
206
|
+
"""
|
|
207
|
+
return await self._sandbox.get_info()
|
|
208
|
+
|
|
209
|
+
async def get_metrics(self) -> SandboxMetrics:
|
|
210
|
+
"""
|
|
211
|
+
Gets the current resource usage metrics for the underlying sandbox.
|
|
212
|
+
|
|
213
|
+
Provides real-time information about CPU usage, memory consumption,
|
|
214
|
+
disk I/O, and other performance metrics.
|
|
215
|
+
|
|
216
|
+
Returns:
|
|
217
|
+
Current sandbox metrics including CPU, memory, and I/O statistics
|
|
218
|
+
|
|
219
|
+
Raises:
|
|
220
|
+
SandboxException: If metrics cannot be retrieved
|
|
221
|
+
"""
|
|
222
|
+
return await self._sandbox.get_metrics()
|
|
223
|
+
|
|
224
|
+
async def renew(self, timeout: timedelta | int) -> None:
|
|
225
|
+
"""
|
|
226
|
+
Renew the sandbox expiration time to delay automatic termination.
|
|
227
|
+
|
|
228
|
+
The new expiration time will be set to the current time plus the provided duration.
|
|
229
|
+
|
|
230
|
+
Args:
|
|
231
|
+
timeout: Duration to add to the current time to set the new expiration.
|
|
232
|
+
Can be timedelta or seconds as int.
|
|
233
|
+
|
|
234
|
+
Raises:
|
|
235
|
+
SandboxException: If the operation fails
|
|
236
|
+
"""
|
|
237
|
+
if isinstance(timeout, int):
|
|
238
|
+
timeout = timedelta(seconds=timeout)
|
|
239
|
+
|
|
240
|
+
logger.info(
|
|
241
|
+
"Renew code interpreter %s timeout, estimated expiration to %s",
|
|
242
|
+
self.id,
|
|
243
|
+
datetime.now(timezone.utc) + timeout,
|
|
244
|
+
)
|
|
245
|
+
await self._sandbox.renew(timeout)
|
|
246
|
+
|
|
247
|
+
async def pause(self) -> None:
|
|
248
|
+
"""
|
|
249
|
+
Pauses the sandbox while preserving its state.
|
|
250
|
+
|
|
251
|
+
The sandbox will transition to PAUSED state and can be resumed later.
|
|
252
|
+
All running processes will be suspended.
|
|
253
|
+
|
|
254
|
+
Raises:
|
|
255
|
+
SandboxException: If pause operation fails
|
|
256
|
+
"""
|
|
257
|
+
logger.info("Pausing code interpreter: %s", self.id)
|
|
258
|
+
await self._sandbox.pause()
|
|
259
|
+
|
|
260
|
+
async def resume(self) -> None:
|
|
261
|
+
"""
|
|
262
|
+
Resumes a previously paused code interpreter.
|
|
263
|
+
|
|
264
|
+
The sandbox will transition from PAUSED to RUNNING state and all
|
|
265
|
+
suspended processes will be resumed.
|
|
266
|
+
|
|
267
|
+
Raises:
|
|
268
|
+
SandboxException: If resume operation fails
|
|
269
|
+
"""
|
|
270
|
+
logger.info("Resuming code interpreter: %s", self.id)
|
|
271
|
+
await self._sandbox.resume()
|
|
272
|
+
|
|
273
|
+
async def kill(self) -> None:
|
|
274
|
+
"""
|
|
275
|
+
This method sends a termination signal to the remote sandbox instance, causing it to stop immediately.
|
|
276
|
+
This is an irreversible operation.
|
|
277
|
+
|
|
278
|
+
Note: This method does NOT close the local `Sandbox` object resources (like connection pools).
|
|
279
|
+
You should call `close()` or use async context manager to clean up local resources.
|
|
280
|
+
|
|
281
|
+
Raises:
|
|
282
|
+
SandboxException: If termination fails
|
|
283
|
+
"""
|
|
284
|
+
logger.info("Killing code interpreter: %s", self.id)
|
|
285
|
+
await self._sandbox.kill()
|
|
286
|
+
|
|
287
|
+
async def is_healthy(self) -> bool:
|
|
288
|
+
"""
|
|
289
|
+
Checks if the code interpreter and its underlying sandbox are healthy and responsive.
|
|
290
|
+
|
|
291
|
+
This performs health checks on both the sandbox infrastructure and code execution services.
|
|
292
|
+
|
|
293
|
+
Returns:
|
|
294
|
+
True if both sandbox and code execution services are healthy, False otherwise
|
|
295
|
+
"""
|
|
296
|
+
return await self._sandbox.is_healthy()
|
|
297
|
+
|
|
298
|
+
@classmethod
|
|
299
|
+
async def create(cls, sandbox: Sandbox) -> "CodeInterpreter":
|
|
300
|
+
"""
|
|
301
|
+
Creates a CodeInterpreter from an existing Sandbox instance.
|
|
302
|
+
|
|
303
|
+
This factory method handles the creation and initialization of CodeInterpreter
|
|
304
|
+
services, including the code execution service and language configuration.
|
|
305
|
+
|
|
306
|
+
CodeInterpreter must be created by wrapping an existing Sandbox instance with
|
|
307
|
+
code execution capabilities. This design ensures clear separation of concerns:
|
|
308
|
+
- Sandbox handles infrastructure (containers, resources, networking)
|
|
309
|
+
- CodeInterpreter adds code execution capabilities on top
|
|
310
|
+
|
|
311
|
+
Args:
|
|
312
|
+
sandbox: Existing sandbox instance to wrap with code execution capabilities
|
|
313
|
+
|
|
314
|
+
Returns:
|
|
315
|
+
CodeInterpreter instance wrapping the sandbox
|
|
316
|
+
|
|
317
|
+
Raises:
|
|
318
|
+
InvalidArgumentException: If sandbox is not provided
|
|
319
|
+
SandboxException: If creation fails
|
|
320
|
+
SandboxInternalException: If internal service initialization fails
|
|
321
|
+
"""
|
|
322
|
+
if sandbox is None:
|
|
323
|
+
raise InvalidArgumentException("Sandbox instance must be provided")
|
|
324
|
+
|
|
325
|
+
logger.info("Creating code interpreter from sandbox: %s", sandbox.id)
|
|
326
|
+
|
|
327
|
+
factory = AdapterFactory(sandbox.connection_config)
|
|
328
|
+
|
|
329
|
+
try:
|
|
330
|
+
# Connect to the execd daemon endpoint for code execution services
|
|
331
|
+
from opensandbox.constants import DEFAULT_EXECD_PORT
|
|
332
|
+
code_interpreter_endpoint = await sandbox.get_endpoint(DEFAULT_EXECD_PORT)
|
|
333
|
+
code_execution_service = factory.create_code_execution_service(code_interpreter_endpoint)
|
|
334
|
+
|
|
335
|
+
logger.info("Code interpreter %s created successfully", sandbox.id)
|
|
336
|
+
|
|
337
|
+
return cls(sandbox, code_execution_service)
|
|
338
|
+
except Exception as e:
|
|
339
|
+
if isinstance(e, SandboxException):
|
|
340
|
+
raise
|
|
341
|
+
raise SandboxInternalException(
|
|
342
|
+
f"Failed to create code interpreter: {e}", cause=e
|
|
343
|
+
) from e
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Copyright 2025 Alibaba Group Holding Ltd.
|
|
3
|
+
#
|
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
# you may not use this file except in compliance with the License.
|
|
6
|
+
# You may obtain a copy of the License at
|
|
7
|
+
#
|
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
#
|
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
# See the License for the specific language governing permissions and
|
|
14
|
+
# limitations under the License.
|
|
15
|
+
#
|
|
16
|
+
"""
|
|
17
|
+
Data models for code execution and interpretation.
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
from code_interpreter.models.code import (
|
|
21
|
+
CodeContext,
|
|
22
|
+
SupportedLanguage,
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
__all__ = [
|
|
26
|
+
"CodeContext",
|
|
27
|
+
"SupportedLanguage",
|
|
28
|
+
]
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Copyright 2025 Alibaba Group Holding Ltd.
|
|
3
|
+
#
|
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
# you may not use this file except in compliance with the License.
|
|
6
|
+
# You may obtain a copy of the License at
|
|
7
|
+
#
|
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
#
|
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
# See the License for the specific language governing permissions and
|
|
14
|
+
# limitations under the License.
|
|
15
|
+
#
|
|
16
|
+
"""
|
|
17
|
+
Code execution models.
|
|
18
|
+
|
|
19
|
+
Models for code contexts, execution requests, and language support.
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
from pydantic import BaseModel, ConfigDict, Field, field_validator
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class SupportedLanguage:
|
|
27
|
+
"""
|
|
28
|
+
Supported programming languages for code execution.
|
|
29
|
+
|
|
30
|
+
This class defines the languages that are officially supported by the code interpreter.
|
|
31
|
+
When adding new languages, ensure corresponding execution environments are available.
|
|
32
|
+
"""
|
|
33
|
+
PYTHON = "python"
|
|
34
|
+
JAVA = "java"
|
|
35
|
+
GO = "go"
|
|
36
|
+
TYPESCRIPT = "typescript"
|
|
37
|
+
BASH = "bash"
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
class CodeContext(BaseModel):
|
|
41
|
+
"""
|
|
42
|
+
Represents an execution context for code interpretation.
|
|
43
|
+
|
|
44
|
+
A CodeContext maintains the execution environment for a specific programming
|
|
45
|
+
language, including the working directory, language configuration, and
|
|
46
|
+
persistent state across multiple code executions.
|
|
47
|
+
|
|
48
|
+
Context Lifecycle:
|
|
49
|
+
|
|
50
|
+
1. Creation: Context is created with language and working directory
|
|
51
|
+
2. Execution: Code runs within this context, building up state
|
|
52
|
+
3. Persistence: Variables, imports, and functions persist between executions
|
|
53
|
+
4. Cleanup: Context can be explicitly destroyed or garbage collected
|
|
54
|
+
"""
|
|
55
|
+
|
|
56
|
+
id: str | None = Field(default=None, description="Unique identifier for this execution context")
|
|
57
|
+
language: str = Field(description="Programming language for this context (e.g., 'python', 'javascript')")
|
|
58
|
+
|
|
59
|
+
@field_validator('language')
|
|
60
|
+
@classmethod
|
|
61
|
+
def language_must_not_be_empty(cls, v: str) -> str:
|
|
62
|
+
if not v.strip():
|
|
63
|
+
raise ValueError("Language cannot be blank")
|
|
64
|
+
return v
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
model_config = ConfigDict(arbitrary_types_allowed=True)
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Copyright 2025 Alibaba Group Holding Ltd.
|
|
3
|
+
#
|
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
# you may not use this file except in compliance with the License.
|
|
6
|
+
# You may obtain a copy of the License at
|
|
7
|
+
#
|
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
#
|
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
# See the License for the specific language governing permissions and
|
|
14
|
+
# limitations under the License.
|
|
15
|
+
#
|
|
16
|
+
"""
|
|
17
|
+
Synchronous code execution models for Code Interpreter SDK.
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
from pydantic import BaseModel, Field, field_validator
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class SupportedLanguageSync:
|
|
24
|
+
# kept for symmetry; values match SupportedLanguage
|
|
25
|
+
PYTHON = "python"
|
|
26
|
+
JAVA = "java"
|
|
27
|
+
GO = "go"
|
|
28
|
+
TYPESCRIPT = "typescript"
|
|
29
|
+
BASH = "bash"
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class CodeContextSync(BaseModel):
|
|
33
|
+
id: str | None = Field(default=None)
|
|
34
|
+
language: str = Field(description="Programming language for this context")
|
|
35
|
+
|
|
36
|
+
@field_validator("language")
|
|
37
|
+
@classmethod
|
|
38
|
+
def language_must_not_be_empty(cls, v: str) -> str:
|
|
39
|
+
if not v.strip():
|
|
40
|
+
raise ValueError("Language cannot be blank")
|
|
41
|
+
return v
|
|
File without changes
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Copyright 2025 Alibaba Group Holding Ltd.
|
|
3
|
+
#
|
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
# you may not use this file except in compliance with the License.
|
|
6
|
+
# You may obtain a copy of the License at
|
|
7
|
+
#
|
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
#
|
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
# See the License for the specific language governing permissions and
|
|
14
|
+
# limitations under the License.
|
|
15
|
+
#
|
|
16
|
+
"""
|
|
17
|
+
Services for code execution and interpretation.
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
from code_interpreter.services.code import Codes
|
|
21
|
+
|
|
22
|
+
__all__ = [
|
|
23
|
+
"Codes",
|
|
24
|
+
]
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Copyright 2025 Alibaba Group Holding Ltd.
|
|
3
|
+
#
|
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
# you may not use this file except in compliance with the License.
|
|
6
|
+
# You may obtain a copy of the License at
|
|
7
|
+
#
|
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
#
|
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
# See the License for the specific language governing permissions and
|
|
14
|
+
# limitations under the License.
|
|
15
|
+
#
|
|
16
|
+
"""
|
|
17
|
+
Code execution service interface.
|
|
18
|
+
|
|
19
|
+
Defines the contract for multi-language code interpretation with context management,
|
|
20
|
+
session persistence, and real-time execution capabilities.
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
from typing import Protocol
|
|
24
|
+
|
|
25
|
+
from opensandbox.models.execd import Execution, ExecutionHandlers
|
|
26
|
+
|
|
27
|
+
from code_interpreter.models.code import CodeContext
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class Codes(Protocol):
|
|
31
|
+
"""
|
|
32
|
+
Code execution service for multi-language code interpretation.
|
|
33
|
+
|
|
34
|
+
This service provides advanced code execution capabilities with context management,
|
|
35
|
+
session persistence, and multi-language support. It extends basic command execution
|
|
36
|
+
with interpreter-specific features like variable inspection and execution history.
|
|
37
|
+
|
|
38
|
+
Supported Languages:
|
|
39
|
+
|
|
40
|
+
- Python: Full Python 3.x support with package management
|
|
41
|
+
- JavaScript/Node.js: ES6+ with npm package support
|
|
42
|
+
- Bash: Shell scripting with full system access
|
|
43
|
+
- Java: Compilation and execution with classpath management
|
|
44
|
+
- Kotlin: Script and compiled Kotlin execution
|
|
45
|
+
|
|
46
|
+
Key Features:
|
|
47
|
+
|
|
48
|
+
- Execution Contexts: Isolated environments with persistent state
|
|
49
|
+
- Variable Persistence: Variables and imports persist across executions
|
|
50
|
+
- Real-time Interruption: Stop long-running code execution safely
|
|
51
|
+
- Output Streaming: Real-time stdout/stderr with proper buffering
|
|
52
|
+
- Error Handling: Language-specific error parsing and reporting
|
|
53
|
+
|
|
54
|
+
Usage Example:
|
|
55
|
+
|
|
56
|
+
```python
|
|
57
|
+
# Create execution context
|
|
58
|
+
context = await code_service.create_context(SupportedLanguage.PYTHON)
|
|
59
|
+
|
|
60
|
+
# Execute code with persistent state
|
|
61
|
+
result1 = await code_service.run(
|
|
62
|
+
"import numpy as np; x = 42",
|
|
63
|
+
context=context,
|
|
64
|
+
)
|
|
65
|
+
|
|
66
|
+
result2 = await code_service.run(
|
|
67
|
+
"print(f'Value: {x}, NumPy version: {np.__version__}')",
|
|
68
|
+
context=context,
|
|
69
|
+
)
|
|
70
|
+
# Variables 'x' and 'np' persist between executions
|
|
71
|
+
```
|
|
72
|
+
"""
|
|
73
|
+
|
|
74
|
+
async def create_context(self, language: str) -> CodeContext:
|
|
75
|
+
"""
|
|
76
|
+
Creates a new execution context for code interpretation.
|
|
77
|
+
|
|
78
|
+
An execution context maintains the state of variables, imports, and working
|
|
79
|
+
directory across multiple code executions. This allows for interactive
|
|
80
|
+
programming sessions where subsequent code can reference previously
|
|
81
|
+
defined variables and functions.
|
|
82
|
+
|
|
83
|
+
Args:
|
|
84
|
+
language: The programming language for this context (e.g., "python", "javascript")
|
|
85
|
+
|
|
86
|
+
Returns:
|
|
87
|
+
A new CodeContext with the specified configuration
|
|
88
|
+
|
|
89
|
+
Raises:
|
|
90
|
+
SandboxException: If the language is not supported or context creation fails
|
|
91
|
+
"""
|
|
92
|
+
...
|
|
93
|
+
|
|
94
|
+
async def run(
|
|
95
|
+
self,
|
|
96
|
+
code: str,
|
|
97
|
+
*,
|
|
98
|
+
context: CodeContext | None = None,
|
|
99
|
+
handlers: ExecutionHandlers | None = None,
|
|
100
|
+
) -> Execution:
|
|
101
|
+
"""
|
|
102
|
+
Executes code within the specified context.
|
|
103
|
+
|
|
104
|
+
This method runs the provided code string in the language interpreter,
|
|
105
|
+
capturing all output, errors, and execution metadata. The execution
|
|
106
|
+
happens within the context's environment, preserving variable state
|
|
107
|
+
and working directory.
|
|
108
|
+
|
|
109
|
+
Execution Behavior:
|
|
110
|
+
|
|
111
|
+
- Asynchronous: Non-blocking execution with proper async handling
|
|
112
|
+
- Stateful: Variables and imports persist in the context
|
|
113
|
+
- Streaming: Output is captured in real-time as it's produced
|
|
114
|
+
- Interruptible: Can be stopped using interrupt() method
|
|
115
|
+
|
|
116
|
+
Args:
|
|
117
|
+
code: Source code to execute.
|
|
118
|
+
context: Execution context (language + optional id). If None, a temporary Python context is used.
|
|
119
|
+
handlers: Optional streaming handlers for stdout/stderr/events.
|
|
120
|
+
|
|
121
|
+
Returns:
|
|
122
|
+
Execution with stdout, stderr, exit code, and execution metadata
|
|
123
|
+
|
|
124
|
+
Raises:
|
|
125
|
+
SandboxException: If execution fails or times out
|
|
126
|
+
"""
|
|
127
|
+
...
|
|
128
|
+
|
|
129
|
+
async def interrupt(self, execution_id: str) -> None:
|
|
130
|
+
"""
|
|
131
|
+
Interrupts a currently running code execution.
|
|
132
|
+
|
|
133
|
+
This method safely terminates a running code execution, cleaning up
|
|
134
|
+
resources and ensuring the interpreter remains in a consistent state.
|
|
135
|
+
The interruption is cooperative and may take some time to complete.
|
|
136
|
+
|
|
137
|
+
Interruption Behavior:
|
|
138
|
+
|
|
139
|
+
- Safe: Preserves interpreter state and doesn't corrupt the context
|
|
140
|
+
- Cooperative: Respects language-specific interruption mechanisms
|
|
141
|
+
- Timeout: Will force-kill after a reasonable timeout if needed
|
|
142
|
+
|
|
143
|
+
Args:
|
|
144
|
+
execution_id: The unique identifier of the execution to interrupt
|
|
145
|
+
|
|
146
|
+
Raises:
|
|
147
|
+
SandboxException: If interruption fails
|
|
148
|
+
"""
|
|
149
|
+
...
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Copyright 2025 Alibaba Group Holding Ltd.
|
|
3
|
+
#
|
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
# you may not use this file except in compliance with the License.
|
|
6
|
+
# You may obtain a copy of the License at
|
|
7
|
+
#
|
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
#
|
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
# See the License for the specific language governing permissions and
|
|
14
|
+
# limitations under the License.
|
|
15
|
+
#
|
|
16
|
+
from code_interpreter.sync.code_interpreter import CodeInterpreterSync
|
|
17
|
+
|
|
18
|
+
__all__ = ["CodeInterpreterSync"]
|