fix(python-sdk): align sync and async implementations#1403
Conversation
Reconcile divergences between the sync and async Python SDKs found while auditing the two trees: - Match `_create` and `Commands._start` parameter ordering to the public signatures and across sync/async; align `Commands.connect` rpc arg order. - Use a consistent bare `Exception` for the internal "Body of the request is None" guard in `sandbox_api` (matching the volume client convention). - Pass keyword args in async `Filesystem.write`; reuse the cached `envd_api_url` property instead of recomputing the sandbox URL. - Align docstrings: deprecation marker, `get_metrics`/`pause`/`write_files` wording, `kill` wording, and a `**seconds**s` typo; add `-> None` to async pty `resize`. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
🦋 Changeset detectedLatest commit: f7609f4 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
PR SummaryMedium Risk Overview
Other changes are consistency-only: matching Reviewed by Cursor Bugbot for commit f7609f4. Bugbot is set up for automated code reviews on this repo. Configure here. |
Package ArtifactsBuilt from 8cde0d5. Download artifacts from this workflow run. JS SDK ( npm install ./e2b-2.28.1-mishushakov-python-sync-async-discrepancies.0.tgzCLI ( npm install ./e2b-cli-2.10.5-mishushakov-python-sync-async-discrepancies.0.tgzPython SDK ( pip install ./e2b-2.26.0+mishushakov.python.sync.async.discrepancies-py3-none-any.whl |
There was a problem hiding this comment.
LGTM — small alignment cleanup; parameter reorderings are safe (all callers use keyword args), and the other changes are equivalent substitutions, docstring fixes, and type annotations.
Extended reasoning...
Overview
This PR aligns the sync and async Python SDK trees: reorders parameters in _create and Commands._start to match the public API, switches Filesystem.write to keyword args, replaces SandboxException with bare Exception for the internal "Body of the request is None" guard (matching the volume client), reuses the cached envd_api_url property in the async constructor, adds a -> None annotation on async pty resize, and aligns several docstrings (deprecation marker, get_metrics/pause/write_files/kill wording, fixes a **seconds**s typo, removes a misleading :return: on pause()).
Security risks
None. No auth, crypto, permission, or input-validation logic is touched. The reordered _create includes secure and allow_internet_access parameters but the values themselves and their semantics are unchanged — only positional order.
Level of scrutiny
Low. This is a consistency/alignment PR with no behavior changes beyond the internal Exception type swap (for a guard that should never fire). The parameter reorderings are safe because every caller uses keyword arguments — verified by grepping all call sites of _create and _start in both sync and async trees. The envd_api_url property substitution in AsyncSandbox.__init__ computes the same value as the previous inline expression (get_sandbox_url(sandbox_id, sandbox_domain)).
Other factors
A changeset is included (patch bump for @e2b/python-sdk). The PR description is precise and accurately enumerates the changes. The author explicitly notes that deeper architectural splits (watch_dir streaming-vs-polling, pty on_data, command output callbacks) are intentionally left untouched, which suggests careful scoping.
`pause()` / `beta_pause()` now return a `bool` (`True` if the sandbox got paused, `False` if it was already paused) in both sync and async, matching the JS SDK. Previously the instance method returned `None` while the class-method form returned the sandbox ID, and the 409 (already-paused) case was indistinguishable from success. Also adds the missing `isinstance(res.parsed, Error)` check to sync `_cls_pause` to match async. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Reconciles divergences found while auditing the sync and async Python SDK trees, keeping behavior equivalent across both (and with the JS SDK where they differed).
pausereturn value:Sandbox.pause()/AsyncSandbox.pause()(andbeta_pause) now return abool—Trueif the sandbox got paused,Falseif it was already paused — matching the JS SDK. Previously the instance method returnedNonewhile the class-method form returned the sandbox ID, and the 409 (already-paused) case was indistinguishable from success. The sync_cls_pausealso gains theisinstance(res.parsed, Error)check that async already had._createandCommands._startsignatures to the public API and to each other, and reordered theCommands.connectrpc args (headersbeforetimeout) to match the_startconvention.sandbox_apinow consistently raises a bareException(matching the volume client) instead of mixingException/SandboxExceptionbetween sync and async.Filesystem.writenow passes keyword args; the async constructor reuses the cachedenvd_api_urlproperty instead of recomputing the sandbox URL; async ptyresizegains a-> Noneannotation.get_metrics/pause/write_files/killwording across sync/async and fixed a**seconds**stypo.The deeper architectural async-vs-sync splits (streaming-vs-polling
watch_dir, ptyon_data, command output callbacks) are intentional and left untouched.🤖 Generated with Claude Code