Commit Graph

205 Commits

Author SHA1 Message Date
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
Mish Ushakov 6ff14f8b2e Add Windows CI to test matrix (#1020)
<!-- CURSOR_SUMMARY -->
> [!NOTE]
> Add Windows to CI matrices and make JS/Python utils and tests
cross-platform via path handling updates.
> 
> - **CI**:
> - Add Windows to test matrices in `cli_tests.yml`, `js_sdk_tests.yml`,
`python_sdk_tests.yml`; set bash shell/workdirs; disable fail-fast for
some jobs.
>   - Python CI runs `pytest -n 4` via Poetry.
> - **JS SDK**:
> - Path normalization for globbing (`normalizePath`) and use of
`Path.relativePosix()` in hashing and tar creation in
`src/template/utils.ts`.
> - **Python SDK**:
> - Add `normalize_path` and use forward-slash glob patterns in
`e2b/template/utils.py`.
> - **Tests**:
> - Make stack trace parsing robust to Windows paths; use `basename` in
file assertions; adjust Python tar tests tempdir fixture handling.
> - **Changeset**: add patch note for windows-related fixes.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
1b8dbe4a1af642dbcb86500837e93f7998b223f6. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: Joseph Lombrozo <joe.lombrozo@e2b.dev>
2025-11-26 09:50:26 -08:00
Mish Ushakov 8be34f8344 Fixes default Dockerfile user/workdir behavior (#1033)
Fixes issue https://github.com/e2b-dev/E2B/issues/1032

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> Preserve Dockerfile USER/WORKDIR when provided and only apply E2B
defaults if absent, with tests and CLI fixtures updated accordingly.
> 
> - **Dockerfile parsing (SDKs)**:
> - **JS (`packages/js-sdk/src/template/dockerfileParser.ts`)**: Track
`USER`/`WORKDIR` usage and only set E2B defaults (`user`, `/home/user`)
if not specified; keep Docker defaults (`root`, `/`) initially.
> - **Python
(`packages/python-sdk/e2b/template/dockerfile_parser.py`)**: Same
behavior—preserve explicit `USER`/`WORKDIR`, fallback to defaults only
when absent.
> - **Tests**:
> - **JS**: Add tests for default vs. custom `USER`/`WORKDIR` in
`fromMethods.test.ts`.
> - **Python (async/sync)**: Add analogous tests in
`test_from_methods.py`.
> - **CLI template fixtures**:
> - Update expected outputs to remove redundant
`.set_user('user')`/`.set_workdir('/home/user')` when already specified;
minor ordering tweak for `.setStartCmd` in TS fixture.
> - **Changeset**:
> - Minor version bumps for `@e2b/python-sdk` and `e2b`; note: keep
Docker `WORKDIR` and `USER` if specified.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
1ce66362501932308292cef87b5d8a73012ee5f2. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
2025-11-26 09:16:25 -08:00
Jakub Dobry 4c612888d4 feat: implement network out allow/deny list support (#1016) 2025-11-15 22:35:09 +00:00
Joseph Lombrozo 98d2c8c0a8 Ensure that httpx transport is reused across calls by default (#997)
This takes some shortcuts in order to keep backwards compatibility.

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> Reuses a singleton httpx transport/client across the SDK, introduces a
generic retry decorator for connect calls, and refactors code/tests to
use the shared clients and fixtures.
> 
> - **SDK (transport/client reuse)**
> - Add global `limits` (configurable via `E2B_*` env vars) and switch
`ApiClient` to accept `transport` instead of `limits`.
> - Introduce `e2b.api.client_async/client_sync` with `get_transport()`
(singleton) and `get_api_client()`; update `Sandbox`/`AsyncSandbox`,
paginators, and sandbox APIs to use them.
> - Remove per-class `_limits` from `SandboxBase`/`TemplateBase`; merge
extra headers correctly; pass `E2b-Sandbox-Port` as string.
> - Template build flows (sync/async) now reuse the API client's
underlying httpx client for file uploads.
> - **Connect client** (`e2b_connect/client.py`)
> - Add `_retry` decorator and apply to unary/server-stream methods;
simplify reconnection logic; minor typing/headers cleanups.
> - **Tests**
> - Add retry unit tests; introduce
`sandbox_factory`/`async_sandbox_factory` and a session `event_loop`;
refactor tests to use factories and shared transports; adjust tar
archive expectations.
> - **Misc**
>   - Add `.editorconfig`, CLI `.envrc`, and changeset entries.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
1d359231b63dc21b6c8d797886f7d6a77c9ed6b7. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: Tomas Valenta <valenta.and.thomas@gmail.com>
Co-authored-by: Mish <10400064+mishushakov@users.noreply.github.com>
2025-11-14 16:48:29 -08:00
Joseph Lombrozo d2e22e3748 Some general pytest cleanup (#1021)
- Individual tests must complete in less than 5 minutes
- Add a `make test` option that runs tests
- Upgrade poetry to 2.1.1 (the lock file was generated by this version,
so this just matches what we already expect)
2025-11-13 17:58:30 -08:00
Mish Ushakov 56d16a8762 Fix ignore files in file upload and added tests (#1012)
<!-- CURSOR_SUMMARY -->
> [!NOTE]
> Ensure file uploads honor ignore patterns (incl. .dockerignore),
refactor file discovery/tar streaming in JS/Python SDKs, and add
comprehensive tests.
> 
> - **File upload behavior**:
> - JS/TS and Python uploads now pass `ignorePatterns` (merged from
`fileIgnorePatterns` and `.dockerignore`) to tar creation, ensuring
ignored files aren’t uploaded.
> - **Refactor/Utilities**:
> - Rename `getAllFilesForFilesHash` -> `getAllFilesInPath` with
optional directory inclusion in both SDKs.
> - Implement `tar_file_stream` (JS and Python) to build archives from
`getAllFilesInPath`, with `noDirRecurse` and symlink control.
>   - Hashing functions updated to use `getAllFilesInPath`.
> - Type tweak: allow `None` in Python `stack_traces` during build wait.
> - **Integration**:
> - JS `uploadFile` and Python async/sync `upload_file` now use tar
streaming with ignore patterns; JS `Template` wires ignore patterns into
uploads.
> - **Tests**:
> - Add extensive tests for `getAllFilesInPath` and `tar_file_stream` in
JS and Python, covering ignore patterns, directories, sorting, and
symlinks.
>   - Remove obsolete tests relying on old function names.
> - **Meta**:
>   - Changeset entries for `@e2b/python-sdk` and `e2b` (patch).
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
2f83444f9006393f33e8c346bec1998b3a06044d. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
2025-11-10 02:59:29 -08:00
Jakub Dobry 6b74009972 feat: add template background build helpers (#1011)
<!-- CURSOR_SUMMARY -->
> [!NOTE]
> Add background template build APIs and build status retrieval to
JS/Python SDKs, change build methods to return BuildInfo, and add tests.
> 
> - **JS SDK (templates)**:
> - Add `Template.buildInBackground` to start builds without waiting and
return `BuildInfo`.
> - Add `Template.getBuildStatus` with optional `logsOffset`; expose
`GetBuildStatusResponse`.
> - Change `Template.build` to return `BuildInfo` and then wait for
completion; refactor internal `build(...)` to accept `ApiClient` and
return identifiers.
> - Add types `AuthOptions`, `BuildInfo`, `GetBuildStatusOptions`; make
`logsOffset` optional in `getBuildStatus` input; update tests with
`backgroundBuild.test.ts`.
> - **Python SDK (templates)**:
> - Introduce `BuildInfo` dataclass;
`Template.build`/`AsyncTemplate.build` now return `BuildInfo`.
> - Add `Template.build_in_background` /
`AsyncTemplate.build_in_background` and `Template.get_build_status` /
`AsyncTemplate.get_build_status`; factor shared `_build`.
> - Export `BuildInfo` in `__init__.py`; add sync/async background build
tests.
> - **Meta**:
>   - Add changeset for patch releases.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
a47f70ea339f6ea2964714a122cde5b7cb5a891b. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
2025-11-06 16:26:27 +01:00
Mish Ushakov 978fbed96f Improve cache hit consistency across environments (#1010) 2025-11-06 06:50:02 -08:00
Mish Ushakov 23adc93f5e Expand folder with double star pattern for recursive hash computation (#994)
Currently, when you provide a simple folder pattern like `folder/` to
copy() it will not check folders contents for changes (only the folder
metadata itself) which leads to stale caches.

This fix appends ** pattern when no pattern is specified for recursive
hash computation.

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> Ensure folder COPY patterns hash contents recursively to fix cache
invalidation, adding a shared file-gathering helper, tests, and a Python
glob dependency.
> 
> - **Template hashing (JS + Python SDKs)**:
> - Add `getAllFilesForFilesHash`
(`packages/js-sdk/src/template/utils.ts`) and
`get_all_files_for_files_hash`
(`packages/python-sdk/e2b/template/utils.py`) to collect directories and
nested files using glob patterns and ignores.
> - Update `calculateFilesHash`/`calculate_files_hash` to use the new
helpers, hashing recursive paths, metadata, and file contents; handle
symlinks consistently.
> - **Tests**:
> - Add comprehensive tests for recursive matching, ignore patterns,
sorting, empty dirs, symlinks in
`packages/js-sdk/tests/.../getAllFilesForFilesHash.test.ts` and Python
async/sync tests under
`packages/python-sdk/tests/.../test_get_all_files_for_files_hash.py`.
> - **Dependencies**:
> - Add `wcmatch` in `packages/python-sdk/pyproject.toml` for advanced
globbing.
> - **Release**:
>   - Patch bump via `.changeset/green-mice-watch.md`.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
d495427d86ad4e4d5a280567baa63df40a3271fb. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: Jakub Dobry <jakub.dobry8@gmail.com>
2025-11-03 16:34:17 +01:00
Mish Ushakov e87576fb7c Dockerfile output - change ENV var syntax (#1004)
Current env var syntax won't be anymore supported by Docker and is
currently blocking local development.

```
3 warnings found (use docker --debug to expand):
 - LegacyKeyValueFormat: "ENV key=value" should be used instead of legacy "ENV key value" format (line 2)
```

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> Use "ENV key=value" in generated Dockerfiles and add tests; minor
devcontainer path string cast.
> 
> - **Template/Dockerfile generation**:
> - **JS SDK (`packages/js-sdk/src/template/index.ts`)**: Handle `ENV`
instructions and output as `ENV key=value ...`.
> - **Python SDK (`packages/python-sdk/e2b/template/main.py`)**: Same
`ENV` formatting; also cast `devcontainer_directory` to `str` in
devcontainer start command.
> - **Tests**:
>   - **JS**: Add `toDockerfile` test covering `ENV` output.
> - **Python (sync/async)**: Add tests for `ENV` output in generated
Dockerfiles.
> - **Changeset**: Patch releases for `@e2b/python-sdk` and `e2b`.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
4a9c504167dd8069551724d83bfa66f0859c1bd4. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
2025-11-01 00:28:06 +01:00
Jakub Novák 742a9ba953 Update connect method (#1001)
<!-- CURSOR_SUMMARY -->
> [!NOTE]
> Use new connect API for JS/Python SDKs to connect and only extend
(never shorten) running sandbox timeouts, with updated types/docs and
tests.
> 
> - **SDKs**:
>   - **JS**:
> - Replace `resume`/`setTimeout` flow with `SandboxApi.connectSandbox`
calling `POST /sandboxes/{sandboxID}/connect`.
> - Update `Sandbox.connect` (static/instance) to use returned
`sandboxDomain`, `envdAccessToken`, `envdVersion`.
> - Redefine `SandboxConnectOpts` to include `timeoutMs` that only
extends existing timeout.
>   - **Python (async/sync)**:
> - Introduce `_cls_connect` using `post_sandboxes_sandbox_id_connect`
with `ConnectSandbox`; return `Sandbox` model.
> - Update `connect` methods to use API response for
domain/token/version; remove extra info fetch.
>     - Docstrings clarify timeout only extends for running sandboxes.
> - **Tests**:
> - Add cases ensuring connect does not shorten timeout and does extend
when longer (JS, async Python, sync Python).
>   - Preserve error on connecting to non-running sandbox.
> - **Meta**:
> - Changeset: minor releases for `@e2b/python-sdk`, `e2b`, and
`@e2b/cli`.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
e76b07990cb4c05e51ba1c51fb5cc7bbd44b991b. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
2025-10-31 05:17:40 -07:00
Mish Ushakov e8576a51e6 Add .fromBunImage and .bunInstall to the SDK (#993)
<!-- CURSOR_SUMMARY -->
> [!NOTE]
> Adds `fromBunImage` and `bunInstall` to JS/Python SDKs, and extends
`npmInstall` with a `dev` flag, with tests across sync/async suites.
> 
> - **Template APIs**:
> - Add `fromBunImage` to start from `oven/bun:<variant>` in
`packages/js-sdk/src/template/index.ts` and
`packages/python-sdk/e2b/template/main.py`.
>   - Add `bunInstall(packages, { g, dev })` in both SDKs.
>   - Extend `npmInstall` to accept `{ dev: boolean }` in both SDKs.
> - **Types/Docs**:
> - Update `packages/js-sdk/src/template/types.ts` to declare
`fromBunImage`, `bunInstall`, and `npmInstall` `dev` option.
> - **Tests**:
> - Add tests for `fromBunImage` and `bunInstall` and update
`npmInstall` (global/dev) in JS (`packages/js-sdk/tests/...`) and Python
sync/async (`packages/python-sdk/tests/...`).
> - **Changeset**:
> - Minor releases for `@e2b/python-sdk` and `e2b`
(`.changeset/silly-lions-buy.md`).
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
b6461d015743d38ba014d724167d2ca256cf7951. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
2025-10-28 16:59:37 +00:00
Jakub Dobry f593bb7004 fix: update dev container naming (#989) 2025-10-24 22:34:45 +00:00