Skip to content

feat: add Volume CRUD operations to SDKs#1126

Open
mishushakov wants to merge 79 commits intomainfrom
mishushakov/volume-crud-sdk
Open

feat: add Volume CRUD operations to SDKs#1126
mishushakov wants to merge 79 commits intomainfrom
mishushakov/volume-crud-sdk

Conversation

@mishushakov
Copy link
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 APIs (including file operations and a separate volume-content client) and threads volumeMounts through sandbox creation in both SDKs, which can affect request payloads and error handling. Most other changes are generated schema/client updates, but the new surface area needs integration verification against the backend.

Overview
Adds Volume support to both SDKs: new Volume/AsyncVolume APIs for create/list/get/destroy plus volume-content operations (list/mkdir/stat/metadata/read/write/remove) backed by a dedicated volume-content OpenAPI client.

Extends sandbox creation to accept volumeMounts/volume_mounts and forwards them to the /sandboxes create request; sandbox info objects now surface returned volumeMounts.

Updates generated OpenAPI schemas/clients to include /volumes endpoints and related models, adds a new JS generate:volume-api script and Python generate-volume-api target, and includes small spec-driven tweaks (e.g., sandbox logs level/search query params, node model field changes, snapshot ID description).

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

@changeset-bot
Copy link

changeset-bot bot commented Feb 10, 2026

🦋 Changeset detected

Latest commit: 526b903

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

@mishushakov
Copy link
Member Author

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

@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
Contributor

github-actions bot commented Feb 18, 2026

Package Artifacts

Built from db65c7f. Download artifacts from this workflow run.

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

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

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

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

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

pip install ./e2b-2.15.3+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

@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".

@mishushakov mishushakov force-pushed the mishushakov/volume-crud-sdk branch from ddc69ae to dea465e Compare March 20, 2026 17:14
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