ai-computer-client 0.1.0__py3-none-any.whl → 0.2.0__py3-none-any.whl
Sign up to get free protection for your applications and to get access to all the features.
- ai_computer/client.py +54 -1
- {ai_computer_client-0.1.0.dist-info → ai_computer_client-0.2.0.dist-info}/METADATA +114 -16
- ai_computer_client-0.2.0.dist-info/RECORD +6 -0
- ai_computer_client-0.1.0.dist-info/RECORD +0 -6
- {ai_computer_client-0.1.0.dist-info → ai_computer_client-0.2.0.dist-info}/WHEEL +0 -0
- {ai_computer_client-0.1.0.dist-info → ai_computer_client-0.2.0.dist-info}/licenses/LICENSE +0 -0
ai_computer/client.py
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
import aiohttp
|
2
2
|
import json
|
3
3
|
import asyncio
|
4
|
-
from typing import Optional, Dict, AsyncGenerator, Union
|
4
|
+
from typing import Optional, Dict, AsyncGenerator, Union, List
|
5
5
|
from dataclasses import dataclass
|
6
6
|
|
7
7
|
@dataclass
|
@@ -241,6 +241,59 @@ class SandboxClient:
|
|
241
241
|
except Exception as e:
|
242
242
|
yield StreamEvent(type="error", data=f"Connection error: {str(e)}")
|
243
243
|
|
244
|
+
async def execute_shell(
|
245
|
+
self,
|
246
|
+
command: str,
|
247
|
+
args: Optional[List[str]] = None,
|
248
|
+
timeout: int = 30
|
249
|
+
) -> SandboxResponse:
|
250
|
+
"""Execute a shell command in the sandbox.
|
251
|
+
|
252
|
+
Args:
|
253
|
+
command: The shell command to execute
|
254
|
+
args: Optional list of arguments for the command
|
255
|
+
timeout: Maximum execution time in seconds
|
256
|
+
|
257
|
+
Returns:
|
258
|
+
SandboxResponse containing execution results
|
259
|
+
"""
|
260
|
+
if not self.token or not self.sandbox_id:
|
261
|
+
return SandboxResponse(success=False, error="Client not properly initialized. Call setup() first")
|
262
|
+
|
263
|
+
# Ensure sandbox is ready
|
264
|
+
ready = await self.wait_for_ready()
|
265
|
+
if not ready.success:
|
266
|
+
return ready
|
267
|
+
|
268
|
+
headers = {
|
269
|
+
"Authorization": f"Bearer {self.token}",
|
270
|
+
"Content-Type": "application/json"
|
271
|
+
}
|
272
|
+
|
273
|
+
data = {
|
274
|
+
"command": command,
|
275
|
+
"args": args or [],
|
276
|
+
"timeout": timeout
|
277
|
+
}
|
278
|
+
|
279
|
+
try:
|
280
|
+
async with aiohttp.ClientSession() as session:
|
281
|
+
async with session.post(
|
282
|
+
f"{self.base_url}/api/v1/sandbox/{self.sandbox_id}/execute/shell",
|
283
|
+
headers=headers,
|
284
|
+
json=data
|
285
|
+
) as response:
|
286
|
+
if response.status != 200:
|
287
|
+
error_text = await response.text()
|
288
|
+
return SandboxResponse(success=False, error=error_text)
|
289
|
+
|
290
|
+
# Parse the response
|
291
|
+
result = await response.json()
|
292
|
+
return SandboxResponse(success=True, data=result)
|
293
|
+
|
294
|
+
except Exception as e:
|
295
|
+
return SandboxResponse(success=False, error=f"Connection error: {str(e)}")
|
296
|
+
|
244
297
|
async def cleanup(self) -> SandboxResponse:
|
245
298
|
"""Delete the sandbox.
|
246
299
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: ai-computer-client
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.2.0
|
4
4
|
Summary: Python client for interacting with the AI Computer service
|
5
5
|
Project-URL: Homepage, https://github.com/ColeMurray/ai-computer-client-python
|
6
6
|
Project-URL: Documentation, https://github.com/ColeMurray/ai-computer-client-python#readme
|
@@ -50,16 +50,34 @@ async def main():
|
|
50
50
|
if not setup_response.success:
|
51
51
|
print(f"Setup failed: {setup_response.error}")
|
52
52
|
return
|
53
|
-
|
53
|
+
|
54
54
|
try:
|
55
|
-
#
|
56
|
-
code = """
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
"""
|
55
|
+
# Example 1: Simple code execution
|
56
|
+
code = """x = 10
|
57
|
+
y = 20
|
58
|
+
result = x + y
|
59
|
+
print(f"The sum is: {result}")"""
|
61
60
|
|
62
|
-
|
61
|
+
print("\nExample 1: Simple execution")
|
62
|
+
print("-" * 50)
|
63
|
+
response = await client.execute_code(code)
|
64
|
+
if response.success:
|
65
|
+
print("Execution result:", response.data)
|
66
|
+
else:
|
67
|
+
print("Execution failed:", response.error)
|
68
|
+
|
69
|
+
# Example 2: Streaming execution
|
70
|
+
code = """import time
|
71
|
+
|
72
|
+
for i in range(5):
|
73
|
+
print(f"Processing step {i + 1}")
|
74
|
+
time.sleep(1) # Simulate work
|
75
|
+
|
76
|
+
result = "Calculation complete!"
|
77
|
+
print(result)"""
|
78
|
+
|
79
|
+
print("\nExample 2: Streaming execution")
|
80
|
+
print("-" * 50)
|
63
81
|
async for event in client.execute_code_stream(code):
|
64
82
|
if event.type == 'stdout':
|
65
83
|
print(f"Output: {event.data}")
|
@@ -80,10 +98,27 @@ if __name__ == "__main__":
|
|
80
98
|
asyncio.run(main())
|
81
99
|
```
|
82
100
|
|
101
|
+
Example output:
|
102
|
+
```
|
103
|
+
Example 1: Simple execution
|
104
|
+
--------------------------------------------------
|
105
|
+
Execution result: {'output': 'The sum is: 30\n', 'sandbox_id': '06a30496-b535-47b0-9fe7-34f7ec483cd7'}
|
106
|
+
|
107
|
+
Example 2: Streaming execution
|
108
|
+
--------------------------------------------------
|
109
|
+
Output: Processing step 1
|
110
|
+
Output: Processing step 2
|
111
|
+
Output: Processing step 3
|
112
|
+
Output: Processing step 4
|
113
|
+
Output: Processing step 5
|
114
|
+
Output: Calculation complete!
|
115
|
+
Execution completed
|
116
|
+
```
|
117
|
+
|
83
118
|
## Features
|
84
119
|
|
85
|
-
- Asynchronous API
|
86
|
-
-
|
120
|
+
- Asynchronous API for efficient execution
|
121
|
+
- Real-time streaming of code output
|
87
122
|
- Automatic sandbox management
|
88
123
|
- Error handling and timeouts
|
89
124
|
- Type hints for better IDE support
|
@@ -94,20 +129,83 @@ if __name__ == "__main__":
|
|
94
129
|
|
95
130
|
The main client class for interacting with the AI Computer service.
|
96
131
|
|
132
|
+
```python
|
133
|
+
client = SandboxClient(base_url="http://aicomputer.dev")
|
134
|
+
```
|
135
|
+
|
97
136
|
#### Methods
|
98
137
|
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
138
|
+
##### `async setup() -> SandboxResponse`
|
139
|
+
Initialize the client and create a sandbox. This must be called before executing any code.
|
140
|
+
|
141
|
+
```python
|
142
|
+
response = await client.setup()
|
143
|
+
if response.success:
|
144
|
+
print("Sandbox ready")
|
145
|
+
```
|
146
|
+
|
147
|
+
##### `async execute_code(code: str, timeout: int = 30) -> SandboxResponse`
|
148
|
+
Execute Python code and return the combined output.
|
149
|
+
|
150
|
+
```python
|
151
|
+
code = """
|
152
|
+
x = 10
|
153
|
+
y = 20
|
154
|
+
result = x + y
|
155
|
+
print(f"The sum is: {result}")
|
156
|
+
"""
|
157
|
+
|
158
|
+
response = await client.execute_code(code)
|
159
|
+
if response.success:
|
160
|
+
print("Output:", response.data['output'])
|
161
|
+
```
|
162
|
+
|
163
|
+
##### `async execute_code_stream(code: str, timeout: int = 30) -> AsyncGenerator[StreamEvent, None]`
|
164
|
+
Execute Python code and stream the output in real-time.
|
165
|
+
|
166
|
+
```python
|
167
|
+
async for event in client.execute_code_stream(code):
|
168
|
+
if event.type == 'stdout':
|
169
|
+
print("Output:", event.data)
|
170
|
+
elif event.type == 'stderr':
|
171
|
+
print("Error:", event.data)
|
172
|
+
```
|
173
|
+
|
174
|
+
##### `async cleanup() -> SandboxResponse`
|
175
|
+
Delete the sandbox and clean up resources.
|
176
|
+
|
177
|
+
```python
|
178
|
+
await client.cleanup()
|
179
|
+
```
|
180
|
+
|
181
|
+
### Response Types
|
182
|
+
|
183
|
+
#### SandboxResponse
|
184
|
+
```python
|
185
|
+
@dataclass
|
186
|
+
class SandboxResponse:
|
187
|
+
success: bool
|
188
|
+
data: Optional[Dict] = None
|
189
|
+
error: Optional[str] = None
|
190
|
+
```
|
191
|
+
|
192
|
+
#### StreamEvent
|
193
|
+
```python
|
194
|
+
@dataclass
|
195
|
+
class StreamEvent:
|
196
|
+
type: str # 'stdout', 'stderr', 'error', 'completed'
|
197
|
+
data: str
|
198
|
+
```
|
104
199
|
|
105
200
|
## Development
|
106
201
|
|
107
202
|
### Running Tests
|
108
203
|
|
109
204
|
```bash
|
205
|
+
# Install development dependencies
|
110
206
|
pip install -e ".[dev]"
|
207
|
+
|
208
|
+
# Run tests
|
111
209
|
pytest
|
112
210
|
```
|
113
211
|
|
@@ -0,0 +1,6 @@
|
|
1
|
+
ai_computer/__init__.py,sha256=g2yDiDT6i24MV3Y2JNfk2ZFkYvxvrN6NXywjZPslXDY,149
|
2
|
+
ai_computer/client.py,sha256=8LgOSO0AD3R8lljblzktIwPLwoAdmX4n-JG58ebd5xY,12119
|
3
|
+
ai_computer_client-0.2.0.dist-info/METADATA,sha256=3XRPWBjdJTIiErS_Kqnoc7iIOOO8LC2QIzc4k3AVHAc,5654
|
4
|
+
ai_computer_client-0.2.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
5
|
+
ai_computer_client-0.2.0.dist-info/licenses/LICENSE,sha256=N_0S5G1Wik2LWVDViJMAM0Z-6vTBX1bvDjb8vouBA-c,1068
|
6
|
+
ai_computer_client-0.2.0.dist-info/RECORD,,
|
@@ -1,6 +0,0 @@
|
|
1
|
-
ai_computer/__init__.py,sha256=g2yDiDT6i24MV3Y2JNfk2ZFkYvxvrN6NXywjZPslXDY,149
|
2
|
-
ai_computer/client.py,sha256=PaBRmSFzgOXNxxQAd3zSCaqzZ8rcvUOhsnFulu40uhc,10214
|
3
|
-
ai_computer_client-0.1.0.dist-info/METADATA,sha256=2kn41kUgglJ8RSC2NOHPLh_rs_O6SXbiUdUUm64OhEY,3487
|
4
|
-
ai_computer_client-0.1.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
5
|
-
ai_computer_client-0.1.0.dist-info/licenses/LICENSE,sha256=N_0S5G1Wik2LWVDViJMAM0Z-6vTBX1bvDjb8vouBA-c,1068
|
6
|
-
ai_computer_client-0.1.0.dist-info/RECORD,,
|
File without changes
|
File without changes
|