Commit Graph

218 Commits

Author SHA1 Message Date
Mish Ushakov 4e16cffc2f feat(js-sdk): add proxy connection param (#1386)
Adds a `proxy` connection parameter to the JS SDK, mirroring the Python
SDK. When set, requests are routed through the given HTTP proxy via an
undici `ProxyAgent` dispatcher (fetchers are cached per-proxy so
non-proxy traffic is unaffected). It applies to control-plane API
requests, all requests made to the returned sandbox (REST plus
filesystem/commands/pty RPC), and volume requests. Behavior is unchanged
when no proxy is provided, and unit tests cover both the API and envd
fetch paths.

## Usage

```ts
import { Sandbox } from 'e2b'

// Routes API + all sandbox requests through the proxy
const sandbox = await Sandbox.create({
  proxy: 'http://user:pass@127.0.0.1:8080',
})
await sandbox.files.write('/hello.txt', 'world')

// Also works when connecting to an existing sandbox
const sbx = await Sandbox.connect(sandboxId, { proxy: 'http://127.0.0.1:8080' })
```

> Proxying relies on the optional `undici` package and the Node runtime;
in browser/edge runtimes requests use global `fetch`, which has no proxy
support (same as the existing HTTP/2 dispatcher).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-09 18:29:16 +02:00
Matt Brockman 6c04e31f68 fix(python-sdk): use thread-local API transports (#1399)
makes the sync python python API http transport cache thread-local to
handle unsafe usage of the shared transport under pressure (e.g.
concurrent template builds). uses the same logic that we were using for
envd.

test
`test_sync_api_transport_cache_reuses_within_thread_and_isolates_across_threads`
fails on main, passes on branch.
2026-06-08 12:36:11 +02:00
Mish Ushakov 08012eeb4a feat: add sendStdin/closeStdin to CommandHandle (#1397)
Adds `sendStdin`/`send_stdin` and `closeStdin`/`close_stdin` directly on
the command handle (JS, Python sync, and Python async) so background
commands can be fed stdin and signalled EOF without reaching back to
`sandbox.commands` with the PID. The handle delegates to the existing
`Commands` methods via closures, mirroring how `kill` is wired, and also
adds the previously-missing `close_stdin`/`aclose_stdin` to the Python
`Commands` class (version-gated on `ENVD_ENVD_CLOSE`, matching JS).
PTY-created handles don't support these and raise a clear error, and the
existing PID-based `Commands.sendStdin` methods are untouched, so the
change is fully backward-compatible. Includes handle-based tests across
all three SDKs and a changeset bumping `e2b` and `@e2b/python-sdk` at
patch.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-08 10:51:39 +02:00
Tomas Valenta 073661a8b5 feat(sdk): add API-only header options (#1395)
## Summary
- Adds `apiHeaders` / `api_headers` for API-only custom headers.
- Deprecates the existing `headers` option in favor of the explicit API
header option.

## Usage
```ts
await Sandbox.create({ apiHeaders: { Authorization: 'Bearer ...' } })
```

```python
sandbox = Sandbox.create(api_headers={"Authorization": "Bearer ..."})
```

## Tests
- Python syntax checks passed for touched files.
- IDE lints and `git diff --check` passed.

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-05 23:25:21 -07:00
Mish Ushakov 5b2bb941de fix(sdk): consistent rate limit error for envd 429 responses (#1387)
## Summary

The main API client already raised `RateLimitError` (JS) /
`RateLimitException` (Python) for HTTP 429, but the lower-level **envd**
HTTP and RPC layers fell through to a generic sandbox error, so the same
rate-limit condition surfaced as a different type depending on which
request path hit it. This maps envd 429 (and the equivalent gRPC
`ResourceExhausted` code) to the dedicated rate-limit error consistently
across the JS SDK and the Python sync/async SDKs. The JS RPC layer was
also missing the `ResourceExhausted` mapping entirely, which is now
added for parity with Python.

## Changes
- `js-sdk/src/envd/api.ts`, `python-sdk/e2b/envd/api.py` — envd HTTP 429
→ `RateLimitError`/`RateLimitException`
- `js-sdk/src/envd/rpc.ts` — added gRPC `Code.ResourceExhausted` →
`RateLimitError`
- Added unit tests for both the envd HTTP and RPC error mappers in JS
and Python
- Changeset (`e2b`: patch)

## Usage example
```ts
import { Sandbox, RateLimitError } from 'e2b'

try {
  await sandbox.files.write('/tmp/file.txt', 'data')
} catch (err) {
  if (err instanceof RateLimitError) {
    // now reliably caught regardless of which request path was rate limited
  }
}
```

```python
from e2b import RateLimitException

try:
    sandbox.files.write("/tmp/file.txt", "data")
except RateLimitException:
    ...
```

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-05 10:44:27 -07:00
Matt Brockman 4b9cc043dc Fix/python envd stable transport (#1368) 2026-05-29 16:39:30 -07:00
Mish Ushakov 4a4bb36839 feat(sdk): validate E2B API key format client-side (#1356)
## Summary

- Both JS and Python SDKs now validate that the configured E2B API key
matches `e2b_` followed by 40 hex characters (mirroring the server-side
check in
[`infra/.../keys/key.go`](https://github.com/e2b-dev/infra/blob/main/packages/shared/pkg/keys/key.go#L66))
and throw `AuthenticationError` / `AuthenticationException` with an
example token (`e2b_0000…`) and a link to the API Keys dashboard tab.
- Validation runs inside `ApiClient` / `ApiClient.__init__` whenever an
API key is present, so callers get immediate, actionable feedback
instead of a generic 401 from the server.
- Added unit tests (`validateApiKey.test.ts`,
`test_validate_api_key.py`) and updated existing fixtures that used
placeholder keys like `'test-key'` / `'base-api-key'` to use the valid
format.

## Test plan

- [x] `pnpm run format`, `pnpm run lint`, `pnpm run typecheck`
- [x] `pnpm exec vitest run tests/api/validateApiKey.test.ts
tests/api/handleApiError.test.ts tests/sandbox/abortSignal.test.ts
tests/template/abortSignal.test.ts
tests/sandbox/configPropagation.test.ts tests/connectionConfig.test.ts`
- [x] `poetry run pytest tests/test_validate_api_key.py
tests/test_api_client_transport.py
tests/sync/sandbox_sync/test_config_propagation.py
tests/async/sandbox_async/test_config_propagation.py
tests/test_connection_config.py`

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-27 21:21:19 +00:00
Mish Ushakov a6bf71a083 fix(sdks): handle multi-source COPY/ADD in fromDockerfile (#1355)
## Summary

- Fixes #1349: `Template.fromDockerfile` (JS) and
`Template.from_dockerfile` (Python) silently dropped intermediate
sources from multi-source `COPY`/`ADD`, keeping only the first one and
producing broken images without warning.
- Both parsers now emit one `copy()` call per source to the same
destination (matching Docker semantics), preserving `--chown` across all
calls.
- Added tests in both SDKs (multi-source COPY, and multi-source COPY
with `--chown`), plus changesets for `e2b` and `@e2b/python-sdk`.

## Test plan

- [x] `pnpm run test tests/template/methods/fromDockerfile.test.ts` (JS)
- [x] `poetry run pytest
tests/{async,sync}/template_*/methods/test_from_dockerfile.py` (Python)
- [x] `pnpm run format` / `pnpm run lint`

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-27 22:57:03 +02:00
Mish Ushakov c485bf5476 feat(sdk): add Sandbox.updateNetwork / update_network (#1337) 2026-05-26 17:12:29 -07:00
Mish Ushakov 3786f34336 feat(sdk): support structured network rules with per-host transforms (#1286) 2026-05-26 16:35:21 -07:00
Jakub Novák 8640378c17 feat(python-sdk): allow opting out of HTTP/2 in get_transport (#1347) 2026-05-22 12:40:00 -07:00
Jakub Novák 2680c89c3e Remove Sandbox.betaCreate / beta_create (#1344)
It didn't have any extra functionality
2026-05-22 16:36:29 +02:00
Tomas Valenta d21b936bf7 fix(sdks): make lifecycle.on_timeout and auto_pause precedence consistent (#1343)
## Summary

When `lifecycle.on_timeout` is set it wins; otherwise we fall back to
the `auto_pause` argument.

Previously the Python SDKs subscripted `lifecycle["on_timeout"]`, which
raised `KeyError` if a caller passed a `lifecycle` dict missing that key
(TypedDict is not enforced at runtime). The JS SDK silently used the
whole `lifecycle` object even when `onTimeout` was undefined. In both
cases, mixing `lifecycle` and `auto_pause` had inconsistent and
surprising behavior across the public surfaces (`create` vs
`beta_create`).

Now both SDKs use `.get`/optional chaining on `on_timeout` and only
treat `lifecycle` as authoritative when that field is actually present.

Touched files:
- `packages/python-sdk/e2b/sandbox_async/sandbox_api.py`
- `packages/python-sdk/e2b/sandbox_sync/sandbox_api.py`
- `packages/js-sdk/src/sandbox/sandboxApi.ts`

---------

Co-authored-by: Jakub Novak <jakub@e2b.dev>
2026-05-22 02:28:18 -07:00
Mish Ushakov eaf452a82b feat: add optional name to createSnapshot and return snapshot names (#1327)
## Summary
- Add optional `name` parameter to `createSnapshot` / `create_snapshot`
in the JS and Python SDKs so callers can name the resulting snapshot
template.
- Return the `names` field from the snapshot API on `SnapshotInfo` (both
in `createSnapshot` responses and in `listSnapshots` paginator results)
so callers can discover the namespaced snapshot names.
- Includes a changeset (`patch` for `e2b` and `@e2b/python-sdk`).

## Test plan
- [ ] `pnpm run format`, `pnpm run lint`, `pnpm run typecheck` all pass
locally
- [ ] Integration tests on a sandbox with valid credentials:
`sandbox.createSnapshot({ name: 'my-snap' })` returns non-empty `names`

Resolves https://github.com/e2b-dev/E2B/issues/1249

---------

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-14 17:22:31 +00:00
Mish Ushakov 575339b163 test(python-sdk): parallelize async sandbox teardown (#1309)
## Summary
- Replace the sequential `for sandbox in sandboxes: await
sandbox.kill()` teardown in `async_sandbox_factory` with
`asyncio.gather(..., return_exceptions=True)` so a failure on one kill
no longer blocks cleanup of the rest, and teardown runs concurrently.
- Hoist the `_test_failed` check above the loop so the failure log is
printed once per fixture rather than per sandbox.

## Test plan
- [ ] `pnpm run format`, `pnpm run lint`, `pnpm run typecheck`
(python-sdk) all pass
- [ ] `pnpm run test` against affected python async sandbox tests

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-14 13:26:47 +00:00
Matt Brockman 20ea715252 Enable HTTP/2 for Python SDK transports for sandbox/main api calls (#1310)
switches python sdk to use http2 for calls to main api + sandboxes

doesn't add it to volumes yet - need to test those separately
2026-05-05 17:23:46 -07:00
Mish Ushakov 55e9e0eb5a chore(deps): resolve Dependabot security alerts across npm and python (#1302)
## Summary

Resolves all 31 open [Dependabot
alerts](https://github.com/e2b-dev/e2b/security/dependabot) across the
workspace.

- **npm** — added range-based `pnpm.overrides` to bump vulnerable
transitive deps to their patched versions: postcss, vite, lodash,
brace-expansion, picomatch (2.x + 4.x), yaml, @tootallnate/once,
smol-toml, flatted, and minimatch (3.x/5.x/9.x/10.x).
- **python-sdk** — bumped dev deps in `poetry.lock`: pytest 7.4 → 9.0.3
(with constraint update in `pyproject.toml`), pytest-asyncio 0.23 → 1.3
(required for pytest 9), python-dotenv 1.2.2, pygments 2.20.0, requests
2.33.1, black 26.3.1; removed 4 now-unused `# ty: ignore` directives
that pytest 9's stricter type signatures made obsolete.

## Test plan

- [x] \`pnpm run typecheck\` passes
- [x] \`pnpm run lint\` passes
- [x] \`pnpm run format\` clean
- [x] CLI tests (80/80) and js-sdk/python-sdk unit tests pass;
integration tests not run locally (need \`E2B_API_KEY\`)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-30 14:45:19 +00:00
Mish Ushakov 3167e19b4f fix(sdk): buffer template upload to set Content-Length, add regression tests (#1294)
## Summary
Consolidates the fix and tests from #1285 and #1293 into a single PR.

- **js-sdk**: `uploadFile` used to pass a Node `Readable` directly to
`fetch`, causing undici to fall back to `Transfer-Encoding: chunked`. S3
presigned PUT URLs reject chunked with 501 NotImplemented. Fix buffers
the archive first so `Content-Length` is set. Includes:
- Regression test that spins up a local HTTP server and asserts
`Content-Length` is set and matches the body, and `Transfer-Encoding` is
not chunked.
- Type-fix for the CLI's typecheck (cast `Pack` →
`AsyncIterable<Buffer>`).
- Dynamic import of `node:stream/consumers` so the browser bundle
doesn't pull it in.
- **python-sdk**: Adds sync + async regression tests for `upload_file`
that guard against the same class of bug (someone swapping
`tar_buffer.getvalue()` for a stream/generator). No Python code change —
the current implementation already passes bytes to `httpx.put(...,
content=...)`.

Authorship of the original JS fix commit preserved (truffle-dev).

Closes #1243.

## Test plan
- [x] `pnpm run test tests/template/uploadFile.test.ts` — passes
- [x] `pnpm run typecheck` / `lint` clean across js-sdk and cli
- [x] `poetry run pytest tests/sync/template_sync/test_upload_file.py
tests/async/template_async/test_upload_file.py -v` — both pass
- [x] `poetry run make format` / `make lint` / `make typecheck` clean

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: truffle <truffleagent@gmail.com>
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-24 07:14:54 -07:00
Mish Ushakov b97fd4dfd0 test: remove apt, bun, npm, pip install tests (#1275)
## Summary
- Deletes install test files for apt, bun, npm, and pip in both JS and
Python SDKs
- Removes sync and async variants in Python
- Stacktrace tests for these install methods are kept

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-24 06:27:23 -07:00
Mish Ushakov c2d6eef78d test: reduce test_sbx_metrics flakiness by extending polling window (#1291)
## Summary
- Bumps metrics polling from 15s to 30s in Python async/sync and JS SDK
tests so the backend has enough headroom to populate metrics under load
— this test was the new #1 CI offender (5/9 Python runs and 4/10 JS runs
failed).
- Raises the async Python sandbox timeout from 20s to 60s for parity
with sync, and adds per-test timeout overrides
(`@pytest.mark.timeout(60)` / `{ timeout: 60_000 }`) so polling can
complete under the default 30s pytest/vitest cap.
- Happy path is unchanged: the loop still breaks as soon as metrics
appear.

## Test plan
- [x] `pnpm run format`, `pnpm run lint`, `pnpm run typecheck` pass
- [x] `test_sbx_metrics` (Python async) passed locally in 8.4s
- [x] `test_sbx_metrics` (Python sync) passed locally in 15.6s
- [x] `metrics.test.ts` (JS) passed locally in 20.7s

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-24 06:03:49 -07:00
Mish Ushakov b5f2631141 feat: add gzip content encoding option for file operations (#1252)
## Summary

- Adds optional `gzip` parameter to sandbox file read/write operations
across JS and Python SDKs
- Uploads are gzip-compressed via `CompressionStream` (JS) /
`gzip.compress` (Python) when enabled, downloads request
`Accept-Encoding: gzip`
- Only applies to the octet-stream upload path (envd >= 0.5.7), so older
envd versions are unaffected
- Includes tests for both SDKs covering write+read with gzip, write gzip
+ read plain, multi-file writes, and byte format reads

## Test plan

- [ ] Run JS SDK content encoding tests (`contentEncoding.test.ts`)
- [ ] Run Python async/sync content encoding tests
(`test_content_encoding.py`)
- [ ] Integration test with envd backend supporting `Content-Encoding:
gzip`

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-03 10:17:53 +00:00
Mish Ushakov 6d7e72e3bd feat: add Volume CRUD operations to SDKs (#1126)
Co-authored-by: Claude Haiku 4.5 <noreply@anthropic.com>
Co-authored-by: Joe Lombrozo <joe.lombrozo@e2b.dev>
2026-03-25 17:37:46 -07:00
Ben Fornefeld 1c55083de0 Fix: Missing default connection config propagation (#1179)
<!-- CURSOR_SUMMARY -->
> [!NOTE]
> **Medium Risk**
> Changes how instance methods merge and forward connection options (api
key/domain/headers/timeouts) to API calls in both JS and Python SDKs,
which can affect request routing and auth headers. Regression tests
reduce risk but behavior changes could impact callers relying on
previous (incorrect) defaults.
> 
> **Overview**
> Fixes **missing propagation of instance `connectionConfig`** when
calling sandbox instance methods (notably `pause`/`betaPause`/`connect`,
plus related methods) so default config is always forwarded and per-call
overrides still win.
> 
> In the JS SDK this centralizes option merging via a new
`resolveApiOpts()` helper and updates multiple `SandboxApi.*` calls to
use it; in the Python SDK it updates `Sandbox.connect()` and
`Sandbox.pause()` (sync + async) to pass
`self.connection_config.get_api_params(**opts)`.
> 
> Adds regression tests in both SDKs to assert defaults are forwarded
and overrides are applied correctly.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
60aa6ca1c386d99613976269106298267d5dbfbe. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
2026-03-23 18:27:29 +01:00
Jakub Novák 5a673d15c8 chore: distinguish between Sandbox and file not found (#1231)
<!-- CURSOR_SUMMARY -->
> [!NOTE]
> **Medium Risk**
> Changes public error/exception types in both JS and Python SDKs by
introducing new subclasses and remapping 404/NotFound conditions, which
may affect downstream error handling despite deprecation shims.
> 
> **Overview**
> **Distinguishes “sandbox not found” from “file/directory not found”
across the SDKs.** Adds `FileNotFound*` and `SandboxNotFound*`
error/exception types (with `NotFound*` marked deprecated) and updates
sandbox lifecycle APIs to throw `SandboxNotFound*` for
missing/non-running sandboxes.
> 
> Refactors envd HTTP/RPC error handling in both JS and Python to
support overridable status/code→error maps, and wires filesystem
operations to map 404/`NotFound` into `FileNotFound*`. Tests are updated
accordingly, and patch changesets are added for both packages.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
73da92694c02f71355b1f8625845c82865bf3b1d. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
2026-03-23 08:59:29 -07:00
Mish Ushakov 222105dc8f fix: include dotfiles in template file uploads (#1162)
## Summary
- Enable glob patterns to match files starting with dot (e.g., `.env`,
`.gitignore`)
- JS SDK: Add `dot: true` to glob calls in `getAllFilesInPath`
- Python SDK: Add `glob.DOTMATCH` flag to glob calls in
`get_all_files_in_path`
- Add comprehensive tests for dotfile handling in both SDKs

Previously, the glob library defaults prevented dotfiles from being
matched, preventing upload of configuration files like `.env`. This fix
enables proper handling of dotfiles in template file uploads.

## Test plan
-  All 16 JS SDK tests pass (4 new dotfile tests)
-  All 17 Python SDK tests pass (4 new dotfile tests)
-  `pnpm run format` passes
-  `pnpm run lint` passes
-  `pnpm run typecheck` passes

🤖 Generated with [Claude Code](https://claude.com/claude-code)

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Low Risk**
> Small, well-scoped change to glob options that only broadens matched
file sets; main risk is unintentionally including hidden files unless
excluded via ignore patterns.
> 
> **Overview**
> Template file collection now includes dot-prefixed files and
directories (e.g., `.env`, `.gitignore`, `.hidden/**`) when
building/uploading templates.
> 
> This updates globbing in the JS SDK’s `getAllFilesInPath` to set `dot:
true` (including recursive directory expansion) and the Python SDK’s
`get_all_files_in_path` to add `glob.DOTMATCH`, and adds targeted tests
in both SDKs to verify dotfile inclusion and that ignore patterns still
exclude specified dotfiles. A changeset bumps both `e2b` and
`@e2b/python-sdk` as patch releases.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
fc3cbcc232bc28559d38bb267162d3f55138b558. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 08:16:16 -08:00
Matt Brockman 7027f369a3 autoresume: lifecycle component in sdk (#1146)
Implements the `lifecycle` prop on `Sandbox.create`, taking over and
deprecating the `beta_pause` functionality.

Currently supports:
- `on_timeout`: `kill` (default) | `pause`. Controls what should happen
to the sandbox when it hits end of life. Pause allows for resuming
- `auto_resume`: False (default) | True. Whether the sandbox should
autoresume on traffic

Intended for additional functionality as we update the backend to
support additional props. Blocked from deploying until the API and
client-proxy are deployed but for pre-approval.

(Meant to be extended later as add more capabilities to the API)

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Changes the API contract and request payload shape for sandbox
auto-resume and alters lifecycle/timeout behavior mapping, which could
break older integrations if backend/client versions are mismatched.
> 
> **Overview**
> Adds a new `lifecycle` configuration on `Sandbox.create` (JS + Python)
to control what happens at timeout (`kill` vs `pause`) and whether
paused sandboxes auto-resume on traffic (`auto_resume`).
> 
> Deprecates `betaPause`/`beta_pause` and the JS `autoPause` create
option in favor of the new lifecycle semantics, updates connect/pause
call paths accordingly, and expands tests to cover resume-on-connect and
auto-resume behaviors.
> 
> Updates the OpenAPI contract and generated clients so `autoResume` is
now an object with an `enabled: boolean` flag (removing the previous
policy enum), and bumps SDK versions via a changeset.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
515f9b7fc13a5ec13db75450e8f6252e3c7bcf03. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
2026-03-04 13:23:08 -08:00
Berry e83cf86454 feat: add getTags/get_tags to list all tags for a template (#1132)
## Summary
- Add `GET /templates/{templateID}/tags` endpoint to the OpenAPI spec
- Add `Template.getTags()` to JS/TS SDK
- Add `Template.get_tags()` (sync) and `AsyncTemplate.get_tags()`
(async) to Python SDK
- Returns a list of `TemplateTag` objects with `tag`, `buildId`, and
`createdAt` fields

## Test plan
- Added unit tests for JS SDK (`Template.getTags` happy path + 404
error)
- Added unit tests for Python SDK (sync + async, happy path + error)
2026-03-03 16:38:39 +01:00
Jakub Dobry 59a0f0478a chore: use template versioning in tests (#1151) 2026-02-26 20:58:20 -08:00
Jakub Dobry 51582e8315 fix: update kill test to use valid sandbox ID format (#1169)
The infra now validates sandbox ID format (^[a-z0-9]+$), allowing only
lowercase alphanumeric characters. The test was using
'non-existing-sandbox' which fails format validation due to hyphens,
returning a 400 error instead of reaching the expected 404 path.

This updates the test to use 'nonexistingsandbox' — a valid format that
doesn't exist, so it properly hits the 404 "not found" response and
returns false as expected.

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Low Risk**
> Low risk: test-only change that updates hardcoded IDs to match new
validation rules, without modifying runtime logic.
> 
> **Overview**
> Updates JS and Python SDK `kill non-existing sandbox` tests to use a
lowercase alphanumeric sandbox ID (`nonexistingsandbox`) instead of a
hyphenated one, so the tests exercise the intended *not-found* path
rather than failing format validation.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
e43acb66ef4465ae60a368ac8c7377023b4a6da3. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: Jakub Novak <jakub@e2b.dev>
2026-02-26 02:08:58 -08:00
Jakub Dobry a55ca219e9 feat: snapshots (#1111) 2026-02-24 11:59:11 -08:00
Jakub Dobry 24279d07b9 fix: scope sandbox_test_id fixture per-test to prevent cross-worker interference (#1149) 2026-02-20 17:50:24 -08:00
Jakub Dobry 85f5b8d2b3 chore: various bug fixes (#1145)
<!-- CURSOR_SUMMARY -->
> [!NOTE]
> **Low Risk**
> Mostly CI/test changes plus a small logging tweak; low production
impact, with main risk being altered test timing/flake behavior due to
new timeout defaults.
> 
> **Overview**
> Improves release-candidate GitHub workflows by passing sanitized
`tag`/`preid` via step `env` vars and quoting them when running `npm
version`/`npm publish`, reducing the chance of input/expansion issues.
> 
> Stabilizes sandbox internet-access tests in JS and Python by switching
the curl target to Google’s `generate_204` endpoint and updating
expected status codes. Python tests also tighten global `pytest` timeout
to 30s, remove per-sandbox default timeouts from fixtures, and add 180s
timeouts specifically for template test suites via new `conftest.py`
files.
> 
> CLI sandbox status polling now logs the caught error when
`Sandbox.getInfo` fails (instead of silently returning `false`).
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
187849338dd46f9d0dd1adb0a070719ebad87309. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
2026-02-18 11:37:32 +01:00
Jakub Dobry 5cc2c8a1ef fix(tests): vitest state cross pollution (#1144) 2026-02-17 17:21:23 -08:00
Jakub Dobry 3033d255bc chore(test): replace netcat with Python HTTP server in network tests (#1140) 2026-02-17 08:18:39 -08:00
Mish Ushakov c38a1819b6 Fix Python SDK type issues with ty type checker (#1122)
## Summary
- Resolved 43 type diagnostics reported by ty (Astral's Python type
checker)
- Fixed Self type issues on class singletons
- Added explicit type annotations for shadowed attributes
- Replaced None with UNSET for auto-generated API parameters
- Fixed method signature alignment for protocol matching
- Added targeted type: ignore suppressions for pattern-based limitations

All checks pass: ty check, ruff format, ruff check.

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Mostly typing/CI changes, but some adjustments affect sandbox
connect/pause overload dispatch and API response/parameter handling
(`UNSET` vs `None`), which could alter edge-case runtime behavior.
> 
> **Overview**
> Fixes Python SDK static typing issues for Astral’s `ty` checker and
wires typechecking into CI.
> 
> Adds a new `Typecheck` GitHub Action plus workspace `typecheck`
scripts (TS packages via `tsc`, Python SDK via `make typecheck` running
`ty`), and publishes a patch changeset for `@e2b/python-sdk`.
> 
> Across the Python SDK, adjusts type annotations and overloads (e.g.,
`Self`/singleton typing, `connect` overloads, optional
`user`/token/domain handling), tightens API model parsing with
`cast`/`Optional` checks and `UNSET` usage, and adds a few targeted `ty`
ignore comments in tests/protocols to silence checker limitations.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
f66402847c40cee7e44e1aaa7caa97e271ba9978. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: Claude Haiku 4.5 <noreply@anthropic.com>
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
2026-02-12 16:23:39 +00:00
Mish Ushakov 5e9c6d6780 feat: validate copy src paths are relative and within context directory (#1106)
Add path validation to the copy method in both JS and Python SDKs to
ensure source paths are always relative and don't escape the context
directory.

This prevents:
- Absolute paths like /absolute/whatever (Unix) or C:\whatever (Windows)
- Path traversal attacks like ../whatever or ./foo/../../../bar

The validation works cross-platform using Node's
path.isAbsolute/normalize and Python's os.path.isabs/normpath plus
PureWindowsPath for detecting Windows paths on Unix.

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Changes behavior of `copy`/`copy_items` to throw earlier for
previously-accepted absolute or escaping paths, which could break some
consumers; logic is localized and well-covered by tests.
> 
> **Overview**
> Prevents path traversal in template `copy` operations by validating
`src` is *relative* and does not escape the context directory (rejects
absolute paths and `..`-based escapes) in both the JS and Python SDKs.
> 
> Updates `copyItems`/`copy_items` error handling to preserve the
caller’s stack trace when validation fails, adds unit coverage for the
new path validator plus new stack-trace tests for absolute-path
failures, and ships as patch releases via a changeset.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
c1a8eb978e3fd99fa829d571e811bb7ee18cd40b. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-05 13:54:54 +01:00
Matt Brockman 1a8fed012c fix: Improve sandbox.git async/sync parity (#1110)
Fixes issue with missing `restore` and `reset` functionality on the
async git sandboxes.
 
Consolidate shared git helpers by moving remote URL argument
construction and
parsing into the git utilities package. Sync and async git modules now
reuse
the same builders where possible, with tests to ensure no drift.

---------

Co-authored-by: Filip Brebera <filip@bxxf.dev>
2026-02-03 11:58:16 -08:00
Matt Brockman 77b08f53e1 Feature: Add Git Support (#1101)
# Sandbox Git Commands

Adds Git support to the sandbox class. This allows the sandbox to manage
git via standard clone, checkout, branch, add, pull, and push commands
without needing to use commands.run. The API mirrors common Git
workflows while handling sandbox-specific concerns like auth injection
and safe remote handling.

**Python example**
```python
from e2b import Sandbox

sandbox = Sandbox.create()
repo_path = '/home/user/my-repo'

# Optional: set author for commits
sandbox.git.configure_user('Your Name', 'you@example.com')

# Clone or init
sandbox.git.clone('https://github.com/org/repo.git', path=repo_path)
# or
sandbox.git.init(repo_path, initial_branch='main')

# Make a change
sandbox.files.write(f'{repo_path}/README.md', '# Hello\n')

# Commit
sandbox.git.add(repo_path, files=['README.md'])
sandbox.git.commit(repo_path, message='Initial commit')

# Branching
sandbox.git.create_branch(repo_path, 'feature1')
# or
sandbox.git.checkout_branch(repo_path, 'main')

# Push
sandbox.git.remote_add(repo_path, 'origin', 'https://github.com/org/repo.git', overwrite=True)
sandbox.git.push(repo_path, remote='origin', branch='main', set_upstream=True)
```

**JavaScript / TypeScript example**
```ts
import { Sandbox } from 'e2b'

const sandbox = await Sandbox.create()
const repoPath = '/home/user/my-repo'

await sandbox.git.configureUser('Your Name', 'you@example.com')

await sandbox.git.clone('https://github.com/org/repo.git', { path: repoPath })
// or
await sandbox.git.init(repoPath, { initialBranch: 'main' })

await sandbox.files.write(`${repoPath}/README.md`, '# Hello\n')

await sandbox.git.add(repoPath, { files: ['README.md'] })
await sandbox.git.commit(repoPath, { message: 'Initial commit' })

await sandbox.git.createBranch(repoPath, 'feature1')
await sandbox.git.checkoutBranch(repoPath, 'main')

await sandbox.git.remoteAdd(repoPath, 'origin', 'https://github.com/org/repo.git', {
  overwrite: true,
})
await sandbox.git.push(repoPath, { remote: 'origin', branch: 'main', setUpstream: true })
```

**Main commands**
- `clone`: Clone a repo into the sandbox. Supports `branch`, `depth`,
optional `username` + `password` for private repos, and
`dangerously_store_credentials` / `dangerouslyStoreCredentials` to keep
credentials in the remote URL.
- `init`: Initialize a new repo. Supports `initial_branch` /
`initialBranch` and `bare`.
- `status`: Get parsed `git status --porcelain -b` info.
- `branches`: List branches and current branch.
- `create_branch` / `createBranch`: Create and check out a new branch.
- `checkout_branch` / `checkoutBranch`: Switch to an existing branch.
- `delete_branch` / `deleteBranch`: Delete a branch. Supports `force`.
- `add`: Stage files. Supports explicit files or `all`.
- `commit`: Create a commit. Supports author override and `allow_empty`.
- `reset` / `reset`: Reset `HEAD` (supports modes like `soft`, `mixed`,
`hard`, etc.) and optional paths.
- `restore` / `restore`: Restore files or unstage changes (`worktree` /
`staged`) from a source ref.
- `pull`: Pull from a remote. Supports `remote`, `branch`, and optional
auth.
- `push`: Push to a remote. Supports `remote`, `branch`, `set_upstream`,
and optional auth.
- `remote_add` / `remoteAdd`: Add a remote. Supports `overwrite` and
`fetch`.
- `remote_get` / `remoteGet`: Read a remote URL.
- `set_config` / `setConfig`: Set a git config value. Supports `scope`
(`global`, `local`, `system`), and `path` for local scope.
- `get_config` / `getConfig`: Read a git config value. Supports the same
`scope` options and returns `None` / `undefined` if unset.
- `dangerously_authenticate` / `dangerouslyAuthenticate`: Persist
credentials via the git credential helper (global).
- `configure_user` / `configureUser`: Set default `user.name` and
`user.email` for commits.
- `create_github_repo` (Python only): Create a GitHub repo from inside
the sandbox and optionally add it as a remote.

**Status shape**
- `status` returns a `GitStatus` with `current_branch` /
`currentBranch`, `upstream`, `ahead`, `behind`, `detached`, and
`file_status` / `fileStatus`.
- `file_status` entries include `name`, `status`, `index_status` /
`indexStatus`, `working_tree_status` / `workingTreeStatus`, `staged`,
and optional `renamed_from` / `renamedFrom`.
- Convenience helpers include: `is_clean` / `isClean`, `has_changes` /
`hasChanges`, `has_staged` / `hasStaged`, `has_untracked` /
`hasUntracked`, `has_conflicts` / `hasConflicts`, plus counts
(`total_count` / `totalCount`, `staged_count` / `stagedCount`,
`unstaged_count` / `unstagedCount`, `untracked_count` /
`untrackedCount`, `conflict_count` / `conflictCount`). In Python these
are properties on the `GitStatus` object; in JS they are fields on the
returned object.

**Notes**
- For private HTTPS remotes, pass `username` + `password` (token) on
`clone`, `pull`, or `push`.
- Use `remote_add` / `remoteAdd` with `overwrite=True` to update an
existing remote URL and `fetch=True` to fetch after.
- Use `dangerously_authenticate` / `dangerouslyAuthenticate` only when
you want to persist credentials globally on the sandbox.
2026-01-29 11:13:15 -08:00
Mish Ushakov 4af9b4c3fc Avoid reading files on upload (#1098)
<!-- CURSOR_SUMMARY -->
> [!NOTE]
> Optimizes file uploads in both JS and Python SDKs to avoid unnecessary
reads and add broader input support.
> 
> - JS SDK: `Filesystem.write`/`writeFiles` now build a single
`FormData` using `toBlob` (new util) to pass
`string`/`ArrayBuffer`/`Blob`/`ReadableStream` without pre-reading;
updated tests add `ReadableStream` coverage
> - Python SDK (sync/async): `write_files` accepts `str`/`bytes`
directly, reads `TextIOBase`, and passes `IOBase` (binary) streams
through without reading; new tests cover `BytesIO` and `StringIO`
> - Changeset: patch bumps for `@e2b/python-sdk` and `e2b`
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
45516e31fa8ba8b678824a6c1adc217287a8effe. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
2026-01-27 15:30:38 -08:00
Mish Ushakov 07ef17f1b0 Rename alias exists > name exists (#1100) 2026-01-27 21:53:37 +01:00
Jakub Dobry 10abab8e96 feat: add template versioning with tags support for JS and Python SDKs (#1080) 2026-01-27 13:41:24 +00:00
Berry c1ee183769 Add writeFiles function to js sdk (#1084)
To fix the inconsistency between the Python SDK and the JS SDK, add
writeFiles to the JS SDK. (no changes made to write function)

---------

Co-authored-by: Mish Ushakov <10400064+mishushakov@users.noreply.github.com>
2026-01-23 15:28:37 +00:00
Jakub Novák ab906adcd3 Fix metrics timestamps (#1083)
<!-- CURSOR_SUMMARY -->
> [!NOTE]
> Aligns metrics APIs to use Unix seconds (no milliseconds) for
`start`/`end` across SDKs.
> 
> - **JS SDK**: `SandboxMetricsOpts` `start`/`end` now `Date` only;
convert to seconds before calling `GET /sandboxes/{sandboxID}/metrics`.
> - **Python SDK (async/sync)**: send `int(timestamp())` for
`start`/`end` instead of milliseconds.
> - **Tests**: JS and Python tests now pass `start`/`end` and validate
non-empty results.
> - **Changesets**: patch notes for `e2b` and `@e2b/python-sdk`.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
7c59f8023fc0de9a5eda7ffd4c588057c7465f3e. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
2026-01-15 08:32:27 -08:00
Mish Ushakov 47fb2ef11d SandboxId-clientId pattern references (#1081)
Remove references to the `sandboxId-clientId` pattern as it is no longer
in use.

We're also converting the long sandbox id's in the API already:
https://github.com/e2b-dev/infra/blob/main/packages/api/internal/handlers/sandbox_get.go#L27

---
<a
href="https://cursor.com/background-agent?bcId=bc-e3bed60d-6524-431f-bce8-4934ddcc81d7"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://cursor.com/open-in-cursor-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://cursor.com/open-in-cursor-light.svg"><img alt="Open in
Cursor"
src="https://cursor.com/open-in-cursor.svg"></picture></a>&nbsp;<a
href="https://cursor.com/agents?id=bc-e3bed60d-6524-431f-bce8-4934ddcc81d7"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://cursor.com/open-in-web-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://cursor.com/open-in-web-light.svg"><img alt="Open in Web"
src="https://cursor.com/open-in-web.svg"></picture></a>

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> Eliminates reliance on the deprecated `sandboxId-clientId` (short ID)
pattern and standardizes on full `sandboxId`.
> 
> - Removes `getShortID` and uses full `sandboxId` in `isRunning` (CLI
`utils.ts`), calling `Sandbox.getInfo` with the complete ID
> - Updates JS SDK tests to compare `sandboxId` via exact equality (no
`split`/`startsWith`) across list and pagination cases for
running/paused sandboxes
> - Updates Python SDK (async/sync) tests similarly to assert exact
`sandbox_id` equality in list and pagination scenarios
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
7ec60a51e5b22ed9b3e90aa46110c016ce0fd73a. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
2026-01-13 17:42:44 +01:00
Jiri Sveceny d8ef36d84f Support Template.aliasExists for JavaScript and Python SDKs (#1068)
Integration tests will fail until the feature is deployed in E2B Cloud
production.

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> Enables checking template alias availability from both SDKs.
> 
> - JS: Implements `checkAliasExists` in `template/buildApi.ts`, exposes
`Template.aliasExists` in `template/index.ts`, adds `AliasExistsOptions`
type and tests
> - Python: Adds `Template.alias_exists` and
`AsyncTemplate.alias_exists` wired to generated
`get_templates_aliases_{alias}` client; includes sync/async tests
> - API: Regenerates schemas/clients to include `GET
/templates/aliases/{alias}`, template build logs endpoint and
parameters, and supporting models (e.g., `TemplateAliasResponse`)
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
4e577fd77888478ac83b66db7537cd2355ea050b. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-12 10:05:48 +00:00
Mish Ushakov dc54fe0200 Parse chown on Docker COPY (#1071)
<!-- CURSOR_SUMMARY -->
> [!NOTE]
> Adds support for parsing ownership on file copy operations in
Dockerfile-based templates.
> 
> - JS: Update `dockerfileParser.ts` to treat `COPY/ADD` as
`ModifiableInstruction`, parse `--chown` via `instruction.getFlags()`,
and pass `user` to `templateBuilder.copy(src, dest, { user })`
> - Python: Update `_handle_copy_instruction` in `dockerfile_parser.py`
to extract `--chown=<user[:group]>` and pass `user` to
`template_builder.copy(src, dest, user=user)`
> - Tests: Add JS and Python (sync/async) tests verifying `COPY --chown`
parsing and argument propagation
> - Changeset: Patch releases for `@e2b/python-sdk` and `e2b`
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
9f3b151be18288bdcc41eaf37157b5d4572f0abf. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
2026-01-09 23:29:40 +01:00
Tomas Valenta 2d5af16b05 Add PTY reconnect (#1053)
<!-- CURSOR_SUMMARY -->
> [!NOTE]
> Introduce `connect` methods to attach to running PTY sessions across
JS and Python SDKs, with tests and default timeout handling.
> 
> - **SDKs**:
>   - **JS (`packages/js-sdk/src/sandbox/commands/pty.ts`)**:
> - Add `Pty.connect(pid, opts?)` to attach to running PTYs; accepts
`PtyConnectOpts` with `onData`, `timeoutMs`, and `requestTimeoutMs`.
> - Factor default PTY connection timeout via
`defaultPtyConnectionTimeout` and apply to `create`/`connect` calls.
>   - **Python**:
> - Async: Add `AsyncSandbox.pty.connect(pid, on_data, timeout?,
request_timeout?)` in `e2b/sandbox_async/commands/pty.py`.
> - Sync: Add `sandbox.pty.connect(pid, timeout?, request_timeout?)` in
`e2b/sandbox_sync/commands/pty.py`.
> - **Tests**:
> - JS: `packages/js-sdk/tests/sandbox/pty/ptyConnect.test.ts` validates
connect/reconnect and output handling.
> - Python: async and sync tests under
`packages/python-sdk/tests/.../pty/test_pty_connect.py` verify
reconnection and exit codes.
> - **Release**:
> - Changeset: minor version bumps for `@e2b/python-sdk` and `e2b`; note
“added option to connect to a running pty session”.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
539c4f518606544dfcef253df5bde49354fe7903. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: Mish <10400064+mishushakov@users.noreply.github.com>
2025-12-22 17:46:35 +00:00
Mish Ushakov 482d20f6e7 Fix Python (sync) WatchHandle test (#1056)
<!-- CURSOR_SUMMARY -->
> [!NOTE]
> Adjusts the watch directory test to modify the file content and scan
returned events for a WRITE on the target file instead of asserting the
first event.
> 
> - **Tests (python-sdk)**:
> - Updates `tests/sync/sandbox_sync/files/test_watch.py`
`test_watch_directory_changes` to:
>     - Write updated content after `watch_dir` is started.
> - Iterate over `handle.get_new_events()` to find a
`FilesystemEventType.WRITE` for the target filename, asserting its
presence.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
f32678e4ed4b141ff9dc498fd9c655f374a66c76. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
2025-12-22 17:34:35 +00:00
Mish Ushakov 7b687bddbb Fixes CMD parser in Python from_dockerfile method (#1040)
What was happening is that the following snippet:

```dockerfile
CMD ["sleep", "20"]
```

Was incorrectly converted to:

```
sleep, 20
```

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> Fixes parsing of Dockerfile CMD/ENTRYPOINT array syntax to a proper
start command and updates tests accordingly.
> 
> - **Python SDK**:
> - `e2b/template/dockerfile_parser.py`: Parse CMD/ENTRYPOINT JSON array
(e.g., `["sleep", "20"]`) into a space-joined command (`sleep 20`) and
set as `start_cmd`.
> - **Tests**:
> - JS SDK and Python (sync/async): Add ENTRYPOINT case and assert
`startCmd`/`_start_cmd` equals `sleep 20`.
> - **Release**:
>   - Changeset: patch bump for `@e2b/python-sdk`.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
ed257ab11e618ece3e5fe70f232a3265fd857ad4. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
2025-12-01 07:40:17 -08:00
Mish Ushakov d911c55c3e Improve CI/CD speed for template tests (#1035)
<!-- CURSOR_SUMMARY -->
> [!NOTE]
> Caches Playwright binaries in JS CI and refactors JS/Python template
tests to use API mocks and aliases, add Dockerfile tests, and update
install APIs to single-package calls.
> 
> - **CI**:
> - Cache Playwright binaries on `ubuntu-22.04` and `windows-latest` in
`.github/workflows/js_sdk_tests.yml` to speed JS SDK tests.
> - **JS SDK Tests**:
> - Extend `buildTemplate` options to accept `alias` in
`tests/setup.ts`.
> - Add `fromDockerfile` tests and switch some builds to
`fromBaseImage`; add build-from-base-template test.
> - Update install method tests to single-package calls for
`aptInstall`, `npmInstall`, `bunInstall`, `pipInstall`.
>   - Tweak `makeSymlink` test order to ensure overwrite behavior.
> - Overhaul stacktrace tests to use `msw` server mocks and alias-based
failure mapping.
> - **Python SDK Tests**:
>   - `build`/`async_build` fixtures accept optional `alias`.
> - Add `from_dockerfile` tests (sync/async); use base image/base
template where applicable.
>   - Update install method tests to single-package calls.
> - Rewrite stacktrace tests to monkeypatch API calls with alias-based
failure mapping.
> - **Dependencies**:
>   - Add dev dependency `msw` to `packages/js-sdk/package.json`.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
1b7f84f4ce692f664c3ce4cdb345f4c3a028b17a. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
2025-11-28 22:34:13 +01:00