Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
83 commits
Select commit Hold shift + click to select a range
5729ee9
chore: reopen PR
mishushakov Feb 10, 2026
0fd233e
feat: add Volume CRUD operations to SDKs
mishushakov Feb 10, 2026
58937ec
updated volume crud client
mishushakov Feb 10, 2026
3e8da70
return bool like sandbox on destroy
mishushakov Feb 10, 2026
0f4ae74
added tests
mishushakov Feb 10, 2026
a900de1
updated msw
mishushakov Feb 10, 2026
c1e27c3
format
mishushakov Feb 10, 2026
c8da307
updated spec
mishushakov Feb 12, 2026
90fd51b
updated spec
mishushakov Feb 12, 2026
071a120
tests
mishushakov Feb 12, 2026
e9dce6e
updated spec
mishushakov Feb 13, 2026
99afdaa
fixes
mishushakov Feb 13, 2026
2da6c7d
aded volume methods
mishushakov Feb 13, 2026
b9223ef
fix
mishushakov Feb 13, 2026
697279e
format
mishushakov Feb 13, 2026
e06b84f
use list_entries to list folder contents
mishushakov Feb 13, 2026
fbc4fef
rename
mishushakov Feb 13, 2026
0ba61f7
resolve lint error
mishushakov Feb 13, 2026
a80e430
type update
mishushakov Feb 13, 2026
eb2a971
return volume mounts in sandbox info
mishushakov Feb 13, 2026
8c1bbb1
updated ty rules
mishushakov Feb 13, 2026
9fc267a
supress warns
mishushakov Feb 13, 2026
5b24544
formatting
mishushakov Feb 13, 2026
8014702
synced implementation with api changes
mishushakov Feb 18, 2026
b5d115c
updated lock file
mishushakov Feb 18, 2026
50bd671
updated semantics
mishushakov Feb 18, 2026
ef03ca8
updated test
mishushakov Feb 18, 2026
13215f0
updated types + exports
mishushakov Feb 18, 2026
c374963
volume errors class
mishushakov Feb 18, 2026
bf08d4c
updated test suite
mishushakov Feb 18, 2026
e6426a6
update js sdk
mishushakov Feb 18, 2026
25842bb
updated the SDK
mishushakov Feb 19, 2026
4ac4d35
format
mishushakov Feb 19, 2026
6048a77
fixes lint and typecheck
mishushakov Feb 19, 2026
c80580b
updated tests (JS)
mishushakov Feb 19, 2026
82fcd91
updated Python SDK and tests
mishushakov Feb 19, 2026
33f1fdc
linter
mishushakov Feb 19, 2026
de5bdbf
format
mishushakov Feb 19, 2026
788cc9c
bugbot suggestions
mishushakov Feb 19, 2026
5706cef
bugbot
mishushakov Feb 19, 2026
1f6246e
bugbot
mishushakov Feb 19, 2026
55ef921
use the same status code check pattern
mishushakov Feb 19, 2026
10a6f0f
moved _convert_volume_entry_stat to utils
mishushakov Feb 19, 2026
47b8763
updated sdk and tests
mishushakov Feb 20, 2026
ecc9914
updated types
mishushakov Feb 20, 2026
8a9694e
updated python http client
mishushakov Feb 20, 2026
c731f64
type check
mishushakov Feb 20, 2026
d698544
type check, handle empty response body on read file
mishushakov Feb 20, 2026
bcc0f2c
updated spec
mishushakov Mar 4, 2026
7eab33b
updated JS SDK client
mishushakov Mar 4, 2026
c6ffe27
/stat > /dir, circular import
mishushakov Mar 4, 2026
34329ef
opts
mishushakov Mar 4, 2026
c41e78a
renamed apikey to token updated mock tests
mishushakov Mar 4, 2026
3f262f2
format
mishushakov Mar 4, 2026
84225d3
lint
mishushakov Mar 4, 2026
dc06a49
rename
mishushakov Mar 5, 2026
b784512
Python Volume Client
mishushakov Mar 5, 2026
759296b
pass typecheck
mishushakov Mar 5, 2026
f04efe0
updated spec
mishushakov Mar 5, 2026
fcfa876
type
mishushakov Mar 5, 2026
141ec07
updated endpoints
mishushakov Mar 5, 2026
3e5b792
updated types
mishushakov Mar 5, 2026
55873a4
fmt
mishushakov Mar 5, 2026
b2b2fb9
implemented suggestion
mishushakov Mar 5, 2026
107422b
js accept type of volume in sandbox create opts
mishushakov Mar 6, 2026
01701db
updated lock file
mishushakov Mar 6, 2026
25ba304
make volume mounts optional as per api spec
mishushakov Mar 6, 2026
d690e38
regenerate the client sdks
djeebus Mar 9, 2026
7d16afc
fix domain names and renamed reference issues
djeebus Mar 9, 2026
54d48f5
fix issues revealed in linting
djeebus Mar 10, 2026
2f07957
updated js client
mishushakov Mar 11, 2026
07a7bea
remove unnecessary bytesio wrapper, pass bytes directly
mishushakov Mar 16, 2026
e720b99
updated SDK + spec
mishushakov Mar 20, 2026
3aabc4e
fmt
mishushakov Mar 20, 2026
3aa01d4
lint
mishushakov Mar 20, 2026
061a350
updated types, tests
mishushakov Mar 20, 2026
b67970a
added binary data tests
mishushakov Mar 20, 2026
308e339
Fix redundant error handling in volume read_file methods
mishushakov Mar 20, 2026
647bb86
updated pnpm-lock
mishushakov Mar 20, 2026
0d424a9
Fix stale volume connection config test expectations
mishushakov Mar 23, 2026
a438207
Resolve pnpm-lock.yaml conflicts with main
mishushakov Mar 23, 2026
7465402
Update pnpm-lock.yaml after rebase on main
mishushakov Mar 23, 2026
fbe8d16
Update pnpm-lock.yaml after rebase on main
mishushakov Mar 24, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .changeset/shiny-wasps-find.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'@e2b/python-sdk': minor
'e2b': minor
---

added volumes support to the SDKs
6 changes: 4 additions & 2 deletions packages/js-sdk/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,10 @@
"example": "tsx example.mts",
"test": "vitest run",
"generate": "npm-run-all generate:* && pnpm run format",
"generate:api": "python ./../../spec/remove_extra_tags.py sandboxes snapshots templates tags auth && openapi-typescript ../../spec/openapi_generated.yml -x api_key --array-length --alphabetize --default-non-nullable false --output src/api/schema.gen.ts",
"generate:api": "python ./../../spec/remove_extra_tags.py sandboxes snapshots templates tags auth volumes && openapi-typescript ../../spec/openapi_generated.yml -x api_key --array-length --alphabetize --default-non-nullable false --output src/api/schema.gen.ts",
"generate:envd": "cd ../../spec/envd && buf generate --template buf-js.gen.yaml\n",
"generate:envd-api": "openapi-typescript ../../spec/envd/envd.yaml -x api_key --array-length --alphabetize --output src/envd/schema.gen.ts",
"generate:volume-api": "openapi-typescript ../../spec/openapi-volumecontent.yml -x api_key --array-length --alphabetize --output src/volume/schema.gen.ts",
"generate:mcp": "json2ts -i ./../../spec/mcp-server.json -o src/sandbox/mcp.d.ts --unreachableDefinitions --style.singleQuote --no-style.semi",
"check-deps": "knip",
"pretest": "npx playwright install --with-deps chromium",
Expand All @@ -56,7 +57,8 @@
"eslint": "^8.57.1",
"json-schema-to-typescript": "^15.0.4",
"knip": "^5.43.6",
"msw": "^2.12.3",
"msw": "^2.12.10",
"npm-check-updates": "^16.14.20",
"npm-run-all": "^4.1.5",
"openapi-typescript": "^7.9.1",
"playwright": "^1.55.1",
Expand Down
165 changes: 154 additions & 11 deletions packages/js-sdk/src/api/schema.gen.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 12 additions & 0 deletions packages/js-sdk/src/errors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -162,3 +162,15 @@ export class FileUploadError extends BuildError {
this.name = 'FileUploadError'
}
}

/**
* Base class for all volume errors.
*
* Thrown when general volume errors occur.
*/
export class VolumeError extends Error {
constructor(message: string) {
super(message)
this.name = 'VolumeError'
}
}
Comment thread
mishushakov marked this conversation as resolved.
12 changes: 12 additions & 0 deletions packages/js-sdk/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export {
RateLimitError,
BuildError,
FileUploadError,
VolumeError,
} from './errors'
export type { Logger } from './logs'

Expand Down Expand Up @@ -90,6 +91,17 @@ export type {
GitStatus,
} from './sandbox/git'

export { Volume, VolumeFileType } from './volume'
export type {
VolumeInfo,
VolumeAndToken,
VolumeEntryStat,
VolumeMetadataOptions,
VolumeWriteOptions,
VolumeApiOpts,
VolumeConnectionConfig,
} from './volume'

export { Sandbox }
import { Sandbox } from './sandbox'

Expand Down
27 changes: 27 additions & 0 deletions packages/js-sdk/src/sandbox/sandboxApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
import { compareVersions } from 'compare-versions'
import { SandboxNotFoundError, TemplateError } from '../errors'
import { timeoutToSeconds } from '../utils'
import type { Volume } from '../volume'
import type { McpServer as BaseMcpServer } from './mcp'

/**
Expand Down Expand Up @@ -156,6 +157,16 @@ export interface SandboxOpts extends ConnectionOpts {
*/
network?: SandboxNetworkOpts

/**
* Volume mounts for the sandbox.
*
* The keys are mount paths inside the sandbox and the values are either
* a `Volume` instance or a string representing the volume name.
*
* @default undefined
*/
volumeMounts?: Record<string, Volume | string>
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Making this an array might be a better idea. It is true that you can only mount each path once, but order may matter. For example:

volumeMounts: [
  { path: "/storage", volume: commonStorage },
  { path: "/storage/private", volume: privateStorage },
]

You can layer it, as long as you can guarantee the order. In a map, the order cannot be guaranteed.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

current version is better DX, don't think order will be important


/**
* Sandbox URL. Used for local development
*/
Expand Down Expand Up @@ -337,6 +348,11 @@ export interface SandboxInfo {
* Sandbox lifecycle configuration.
*/
lifecycle?: SandboxInfoLifecycle

/**
* Volume mounts for the sandbox.
*/
volumeMounts?: Array<{ name: string; path: string }>
}

/**
Expand Down Expand Up @@ -602,6 +618,7 @@ export class SandboxApi {
}
: undefined,
sandboxDomain: res.data.domain || undefined,
volumeMounts: res.data.volumeMounts ?? [],
}
}

Expand Down Expand Up @@ -775,6 +792,15 @@ export class SandboxApi {
: {}),
}

if (opts?.volumeMounts) {
body.volumeMounts = Object.entries(opts.volumeMounts).map(
([mountPath, vol]) => ({
name: typeof vol === 'string' ? vol : vol.name,
path: mountPath,
})
)
}

const res = await client.api.POST('/sandboxes', {
body,
signal: config.getSignal(opts?.requestTimeoutMs),
Expand Down Expand Up @@ -959,6 +985,7 @@ export class SandboxPaginator extends BasePaginator<SandboxInfo> {
cpuCount: sandbox.cpuCount,
memoryMB: sandbox.memoryMB,
envdVersion: sandbox.envdVersion,
volumeMounts: sandbox.volumeMounts ?? [],
})
)
}
Expand Down
Loading
Loading