Conversation
| source_devbox: AsyncDevbox | None = None | ||
| clone_a: AsyncDevbox | None = None | ||
| clone_b: AsyncDevbox | None = None | ||
| snapshot: AsyncSnapshot | None = None | ||
| local_file_path: Path | None = None | ||
|
|
||
| source_needs_cleanup = False | ||
| clone_a_needs_cleanup = False | ||
| clone_b_needs_cleanup = False | ||
| snapshot_needs_cleanup = False | ||
|
|
||
| async def cleanup_source() -> None: | ||
| if source_needs_cleanup and source_devbox is not None: | ||
| await source_devbox.shutdown() | ||
|
|
||
| async def cleanup_clone_a() -> None: | ||
| if clone_a_needs_cleanup and clone_a is not None: | ||
| await clone_a.shutdown() | ||
|
|
||
| async def cleanup_clone_b() -> None: | ||
| if clone_b_needs_cleanup and clone_b is not None: | ||
| await clone_b.shutdown() | ||
|
|
||
| async def cleanup_snapshot() -> None: | ||
| if snapshot_needs_cleanup and snapshot is not None: | ||
| await snapshot.delete() | ||
|
|
||
| def cleanup_local_file() -> None: | ||
| if local_file_path is not None: | ||
| local_file_path.unlink(missing_ok=True) | ||
|
|
||
| # Cleanup runs in LIFO order, so register these handlers up front in reverse | ||
| # dependency order: clones, then source devbox, then snapshot, then local file. | ||
| cleanup.add("local-file:snapshot-demo", cleanup_local_file) | ||
| cleanup.add("snapshot:baseline", cleanup_snapshot) | ||
| cleanup.add("devbox:source", cleanup_source) | ||
| cleanup.add("devbox:clone-a", cleanup_clone_a) | ||
| cleanup.add("devbox:clone-b", cleanup_clone_b) |
There was a problem hiding this comment.
is this really needed? devbox_snapshot_resume.py does this in one line: cleanup.add(f"devbox:{dbx_original.id}", dbx_original.shutdown). we could probably use the same pattern here after creation for each resource that needs cleanup
| suspend_response = await source_devbox.suspend() | ||
| suspended_info = suspend_response |
There was a problem hiding this comment.
this is the only time suspend_response is referenced. just replace with suspended_info
| clone_a = await snapshot.create_devbox( | ||
| name=unique_name("snapshot-clone-a"), | ||
| launch_parameters={ | ||
| "resource_size_request": "X_SMALL", | ||
| }, | ||
| ) | ||
| clone_a_needs_cleanup = True | ||
| resources_created.append(f"devbox:{clone_a.id}") | ||
|
|
||
| clone_b = await sdk.devbox.create_from_snapshot( | ||
| snapshot.id, | ||
| name=unique_name("snapshot-clone-b"), | ||
| launch_parameters={ | ||
| "resource_size_request": "X_SMALL", | ||
| }, | ||
| ) |
There was a problem hiding this comment.
add comment about demonstrating two different ways of starting a devbox from snapshot, can be confusing otherwise
| ), | ||
| ExampleCheck( | ||
| name="snapshot can be deleted after the demo finishes", | ||
| passed=not snapshot_needs_cleanup, |
There was a problem hiding this comment.
should always pass if we reach this point, right? we should either remove this check or replace it with something that actually queries the api to verify the snapshot was deleted/is no longer listed
| ## Examples | ||
|
|
||
| Workflow-oriented runnable examples are documented in [`EXAMPLES.md`](./EXAMPLES.md). | ||
| For a suspend/resume plus shared snapshot restore workflow, see [`examples/devbox_snapshots.py`](./examples/devbox_snapshots.py). |
There was a problem hiding this comment.
this is the only example that gets a dedicated callout in the main README. why?
There was a problem hiding this comment.
overall looks good, but seems very similar to devbox_snapshot_resume.py. could these two be consolidated into one example?
Adds the last of the examples for basic devbox operations.