|
7 | 7 | - Streaming stderr |
8 | 8 | - Streaming combined output |
9 | 9 | - Processing output line-by-line |
10 | | -- Async streaming callbacks |
| 10 | +- Using synchronous callbacks (async callbacks not supported) |
11 | 11 | """ |
12 | 12 |
|
13 | 13 | import os |
@@ -76,7 +76,7 @@ def demonstrate_combined_streaming(sdk: RunloopSDK): |
76 | 76 | print(f"Created devbox: {devbox.id}\n") |
77 | 77 |
|
78 | 78 | # Track all output |
79 | | - all_output = [] |
| 79 | + all_output: list[tuple[str, str]] = [] |
80 | 80 |
|
81 | 81 | def capture_all(line: str): |
82 | 82 | timestamp = datetime.now().strftime("%H:%M:%S.%f")[:-3] |
@@ -159,7 +159,7 @@ def demonstrate_long_running_stream(sdk: RunloopSDK): |
159 | 159 | with sdk.devbox.create(name="streaming-longrun-devbox") as devbox: |
160 | 160 | print(f"Created devbox: {devbox.id}\n") |
161 | 161 |
|
162 | | - progress_items = [] |
| 162 | + progress_items: list[str] = [] |
163 | 163 |
|
164 | 164 | def track_progress(line: str): |
165 | 165 | line = line.rstrip() |
@@ -188,46 +188,35 @@ def track_progress(line: str): |
188 | 188 |
|
189 | 189 |
|
190 | 190 | async def demonstrate_async_streaming(): |
191 | | - """Demonstrate async streaming with async callbacks.""" |
192 | | - print("\n=== Async Streaming ===") |
| 191 | + """Demonstrate async devbox with synchronous callbacks. |
| 192 | +
|
| 193 | + Note: Callbacks must be synchronous functions, not async. |
| 194 | + Use thread-safe queues if you need to process output asynchronously. |
| 195 | + """ |
| 196 | + print("\n=== Async Devbox with Synchronous Callbacks ===") |
193 | 197 |
|
194 | 198 | sdk = AsyncRunloopSDK() |
195 | 199 |
|
196 | | - async with sdk.devbox.create(name="async-streaming-devbox") as devbox: |
| 200 | + async with await sdk.devbox.create(name="async-streaming-devbox") as devbox: |
197 | 201 | print(f"Created devbox: {devbox.id}\n") |
198 | 202 |
|
199 | | - # Async callback with async operations |
200 | | - output_queue = asyncio.Queue() |
201 | | - |
202 | | - async def async_capture(line: str): |
203 | | - # Simulate async processing (e.g., writing to a database) |
204 | | - await asyncio.sleep(0.01) |
205 | | - await output_queue.put(line.rstrip()) |
206 | | - print(f"[ASYNC] {line.rstrip()}") |
207 | | - |
208 | | - # Start processing task |
209 | | - async def process_queue(): |
210 | | - processed = [] |
211 | | - while True: |
212 | | - try: |
213 | | - line = await asyncio.wait_for(output_queue.get(), timeout=2.0) |
214 | | - processed.append(line) |
215 | | - except asyncio.TimeoutError: |
216 | | - break |
217 | | - return processed |
218 | | - |
219 | | - processor = asyncio.create_task(process_queue()) |
220 | | - |
221 | | - # Execute with async streaming |
222 | | - print("Streaming with async callbacks:") |
| 203 | + # Synchronous callback (callbacks must be sync, not async) |
| 204 | + output_lines: list[str] = [] |
| 205 | + |
| 206 | + def capture_output(line: str): |
| 207 | + # Callback must be synchronous |
| 208 | + output_lines.append(line.rstrip()) |
| 209 | + print(f"[CAPTURED] {line.rstrip()}") |
| 210 | + |
| 211 | + # Execute with synchronous callback |
| 212 | + print("Streaming with synchronous callbacks:") |
223 | 213 | await devbox.cmd.exec( |
224 | | - 'for i in 1 2 3 4 5; do echo "Async line $i"; sleep 0.2; done', |
225 | | - stdout=async_capture, |
| 214 | + 'for i in 1 2 3 4 5; do echo "Line $i"; sleep 0.2; done', |
| 215 | + stdout=capture_output, |
226 | 216 | ) |
227 | 217 |
|
228 | | - # Wait for queue processing |
229 | | - processed = await processor |
230 | | - print(f"\nProcessed {len(processed)} lines asynchronously") |
| 218 | + print(f"\nCaptured {len(output_lines)} lines") |
| 219 | + print(f"Output: {output_lines}") |
231 | 220 |
|
232 | 221 |
|
233 | 222 | def main(): |
|
0 commit comments