Skip to content

feat: add Volume CRUD operations to SDKs#1126

Merged
djeebus merged 83 commits intomainfrom
mishushakov/volume-crud-sdk
Mar 26, 2026
Merged

feat: add Volume CRUD operations to SDKs#1126
djeebus merged 83 commits intomainfrom
mishushakov/volume-crud-sdk

Conversation

@mishushakov
Copy link
Copy Markdown
Member

@mishushakov mishushakov commented Feb 10, 2026

Summary

Add Volume CRUD operations to both TypeScript and Python SDKs. Volumes are persistent storage that can be mounted to sandboxes. Includes create, list, get_info, and destroy methods. Sandbox creation now supports volumeMounts parameter.

  • Updated OpenAPI spec with volume endpoints and schemas
  • Generated API clients for both SDKs using codegen
  • Implemented Volume class in TypeScript with static methods
  • Implemented sync/async Volume classes in Python with same API
  • Added volumeMounts support to Sandbox creation flow
  • Added volume tag to codegen filters for spec filtering

Usage Examples

TypeScript

import { Volume, Sandbox } from 'e2b'

// Create a volume
const volume = await Volume.create('my-data')
console.log(volume.volumeId, volume.name)

// List all volumes
const volumes = await Volume.list()

// Get volume info
const info = await Volume.getInfo(volume.volumeId)

// File operations on a volume
await volume.writeFile('/data/hello.txt', 'Hello, World!')
const content = await volume.readFile('/data/hello.txt')

// Directory operations
await volume.makeDir('/data/subdir', { force: true })
const entries = await volume.list('/data')

// Check if a path exists
const exists = await volume.exists('/data/hello.txt')

// Get file/directory info
const stat = await volume.getInfo('/data/hello.txt')

// Remove files
await volume.remove('/data/hello.txt')
await volume.remove('/data/subdir', { recursive: true })

// Mount a volume to a sandbox
const sandbox = await Sandbox.create('base', {
  volumeMounts: {
    '/mnt/data': volume,       // mount by Volume instance
    '/mnt/other': 'other-vol', // mount by volume name
  },
})

// Connect to an existing volume
const existing = await Volume.connect(volume.volumeId)

// Destroy a volume
await Volume.destroy(volume.volumeId)

Python (async)

from e2b import AsyncSandbox, AsyncVolume

# Create a volume
volume = await AsyncVolume.create("my-data")
print(volume.volume_id, volume.name)

# List all volumes
volumes = await AsyncVolume.list()

# Get volume info
info = await AsyncVolume.get_info(volume.volume_id)

# File operations on a volume
await volume.write_file("/data/hello.txt", "Hello, World!")
content = await volume.read_file("/data/hello.txt")

# Directory operations
await volume.make_dir("/data/subdir", force=True)
entries = await volume.list("/data")

# Check if a path exists
exists = await volume.exists("/data/hello.txt")

# Get file/directory info
stat = await volume.get_info("/data/hello.txt")

# Remove files
await volume.remove("/data/hello.txt")
await volume.remove("/data/subdir", recursive=True)

# Mount a volume to a sandbox
sandbox = await AsyncSandbox.create(
    "base",
    volume_mounts={
        "/mnt/data": volume,       # mount by Volume instance
        "/mnt/other": "other-vol", # mount by volume name
    },
)

# Connect to an existing volume
existing = await AsyncVolume.connect(volume.volume_id)

# Destroy a volume
await AsyncVolume.destroy(volume.volume_id)

Python (sync)

from e2b import Sandbox, Volume

# Create a volume
volume = Volume.create("my-data")
print(volume.volume_id, volume.name)

# List all volumes
volumes = Volume.list()

# Get volume info
info = Volume.get_info(volume.volume_id)

# File operations on a volume
volume.write_file("/data/hello.txt", "Hello, World!")
content = volume.read_file("/data/hello.txt")

# Directory operations
volume.make_dir("/data/subdir", force=True)
entries = volume.list("/data")

# Check if a path exists
exists = volume.exists("/data/hello.txt")

# Get file/directory info
stat = volume.get_info("/data/hello.txt")

# Remove files
volume.remove("/data/hello.txt")
volume.remove("/data/subdir", recursive=True)

# Mount a volume to a sandbox
sandbox = Sandbox.create(
    "base",
    volume_mounts={
        "/mnt/data": volume,       # mount by Volume instance
        "/mnt/other": "other-vol", # mount by volume name
    },
)

# Connect to an existing volume
existing = Volume.connect(volume.volume_id)

# Destroy a volume
Volume.destroy(volume.volume_id)

Testing

  • TypeScript build passes with no type errors
  • Python imports work and classes are instantiable
  • Both SDKs pass format and lint checks
  • Generated API client models use correct field mappings (id/name)

Note

Medium Risk
Adds new volume-management and volume-content APIs plus sandbox volumeMounts/volume_mounts wiring, which introduces new network calls and token handling paths. Risk is moderate due to the size of generated client changes and expanded surface area, but it’s largely additive.

Overview
Adds Volumes support across the TypeScript and Python SDKs, including new Volume/AsyncVolume APIs for creating, listing, fetching, and destroying volumes, plus volume content operations (dir listing, metadata updates, upload/download, and delete) via a dedicated volume-content OpenAPI client.

Extends sandbox creation options to accept volumeMounts (JS) / volume_mounts (Python) and plumbs these through to the sandbox create request and returned SandboxInfo. Also updates generated API schemas (new /volumes endpoints; log query now supports level/search) and adds SDK tests/fixtures for volume behavior, along with codegen script updates and a changeset for minor version bumps.

Written by Cursor Bugbot for commit caabe40. This will update automatically on new commits. Configure here.

@changeset-bot
Copy link
Copy Markdown

changeset-bot bot commented Feb 10, 2026

🦋 Changeset detected

Latest commit: fbe8d16

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 2 packages
Name Type
@e2b/python-sdk Minor
e2b Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

Comment thread packages/js-sdk/src/sandbox/sandboxApi.ts Outdated
Comment thread packages/js-sdk/src/volume.ts Outdated
Comment thread packages/js-sdk/src/volume.ts Outdated
Comment thread packages/js-sdk/src/volume.ts Outdated
Comment thread packages/js-sdk/src/volume.ts Outdated
Comment thread packages/python-sdk/e2b/sandbox_async/main.py Outdated
Comment thread packages/python-sdk/e2b/sandbox_async/main.py Outdated
Comment thread packages/python-sdk/e2b/sandbox_async/main.py Outdated
Comment thread packages/js-sdk/src/sandbox/sandboxApi.ts Outdated
Comment thread packages/python-sdk/e2b/sandbox_async/main.py Outdated
@mishushakov
Copy link
Copy Markdown
Member Author

@djeebus no need to review, it's a draft

Comment thread packages/python-sdk/e2b/sandbox_async/sandbox_api.py Outdated
Comment thread packages/python-sdk/e2b/volume_info.py Outdated
@mishushakov mishushakov force-pushed the mishushakov/volume-crud-sdk branch from 019d887 to e11378c Compare February 10, 2026 21:19
@mishushakov mishushakov reopened this Feb 10, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Feb 18, 2026

Package Artifacts

Built from a045db3. Download artifacts from this workflow run.

JS SDK (e2b@2.16.1-mishushakov-volume-crud-sdk.0):

npm install ./e2b-2.16.1-mishushakov-volume-crud-sdk.0.tgz

CLI (@e2b/cli@2.9.1-mishushakov-volume-crud-sdk.0):

npm install ./e2b-cli-2.9.1-mishushakov-volume-crud-sdk.0.tgz

Python SDK (e2b==2.17.0+mishushakov-volume-crud-sdk):

pip install ./e2b-2.17.0+mishushakov.volume.crud.sdk-py3-none-any.whl

@mishushakov mishushakov marked this pull request as ready for review February 19, 2026 14:14
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 8ae99f53cf

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread packages/js-sdk/src/volume/index.ts Outdated
Comment thread packages/js-sdk/src/volume/index.ts Outdated
Comment thread packages/js-sdk/src/volume/index.ts
Comment thread packages/js-sdk/src/sandbox/sandboxApi.ts Outdated
Comment thread packages/js-sdk/src/volume/index.ts
Comment thread packages/js-sdk/src/volume/index.ts
Comment thread packages/js-sdk/tests/volume/file.test.ts Outdated
Comment thread packages/js-sdk/src/volume/index.ts Outdated
Comment thread packages/js-sdk/src/volume/index.ts
Comment thread packages/js-sdk/src/volume/types.ts
Comment thread packages/js-sdk/src/volume/index.ts Outdated
Comment thread packages/js-sdk/src/errors.ts
Comment thread packages/python-sdk/e2b/volume/volume_async.py Outdated
Comment thread packages/python-sdk/e2b/api/client/models/listed_sandbox.py
Comment thread packages/js-sdk/src/volume/index.ts
Comment thread packages/js-sdk/tests/setup.ts
mishushakov and others added 26 commits March 25, 2026 00:26
Simplify handle_api_exception usage in read_file (both sync and async)
to use direct `raise` instead of storing in a variable and checking.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Update Python SDK tests to match current API URL defaults
(api.{domain} instead of volumecontent.{domain}, localhost:8080
instead of localhost:3000 for debug mode).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@mishushakov mishushakov force-pushed the mishushakov/volume-crud-sdk branch from caabe40 to fbe8d16 Compare March 24, 2026 23:27
@cursor
Copy link
Copy Markdown

cursor bot commented Mar 24, 2026

PR Summary

Medium Risk
Adds new Volume APIs (including file operations) and propagates volumeMounts into sandbox creation, which may affect request payload compatibility and error handling across both SDKs. Most changes are additive but span generated clients and core SDK entrypoints.

Overview
Adds first-class Volumes support to both SDKs: new volume CRUD endpoints/types are generated and exposed, plus a new JS Volume client with volume-content operations (list/read/write/mkdir/metadata/remove) backed by a dedicated volume API client.

Extends sandbox creation/listing in both JS and Python to accept/return volumeMounts and serialize mounts as {name, path}. Also updates the generated sandboxes logs API to support level/search filters, updates Python exports/exceptions, and refreshes codegen scripts/deps to include the new volumes tag and volume-content OpenAPI spec.

Written by Cursor Bugbot for commit fbe8d16. This will update automatically on new commits. Configure here.

@djeebus djeebus merged commit 6d7e72e into main Mar 26, 2026
86 of 131 checks passed
@djeebus djeebus deleted the mishushakov/volume-crud-sdk branch March 26, 2026 00:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants