Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
Empty file added AUTO_RESUME.md
Empty file.
Original file line number Diff line number Diff line change
Expand Up @@ -494,6 +494,12 @@ sandbox instance for the new sandbox.
const sandbox = await Sandbox.create()
```

```ts
const sandbox = await Sandbox.create({
autoResume: { policy: 'any' },
})
```

###### Constructs

Sandbox
Expand Down
11 changes: 11 additions & 0 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.

40 changes: 29 additions & 11 deletions packages/js-sdk/src/sandbox/sandboxApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,15 @@ export type SandboxNetworkOpts = {
maskRequestHost?: string
}

export type SandboxAutoResumePolicy = 'any' | 'off'

export type SandboxAutoResumeConfig = {
/**
* Auto-resume policy for paused sandboxes. Default is `off`.
*/
policy?: SandboxAutoResumePolicy
}

/**
* Options for request to the Sandbox API.
*/
Expand Down Expand Up @@ -118,6 +127,12 @@ export interface SandboxOpts extends ConnectionOpts {
*/
allowInternetAccess?: boolean

/**
* Auto-resume configuration for paused sandboxes. Omit to disable auto-resume.
* @default undefined
*/
autoResume?: SandboxAutoResumeConfig

/**
* MCP server to enable in the sandbox
* @default undefined
Expand Down Expand Up @@ -537,18 +552,21 @@ export class SandboxApi {
const config = new ConnectionConfig(opts)
const client = new ApiClient(config)

const body = {
autoPause: opts?.autoPause ?? false,
...(opts?.autoResume == null ? {} : { autoResume: opts.autoResume }),
templateID: template,
metadata: opts?.metadata,
mcp: opts?.mcp as Record<string, unknown> | undefined,
envVars: opts?.envs,
timeout: timeoutToSeconds(timeoutMs),
secure: opts?.secure ?? true,
allow_internet_access: opts?.allowInternetAccess ?? true,
network: opts?.network,
}

const res = await client.api.POST('/sandboxes', {
body: {
autoPause: opts?.autoPause ?? false,
templateID: template,
metadata: opts?.metadata,
mcp: opts?.mcp as Record<string, unknown> | undefined,
envVars: opts?.envs,
timeout: timeoutToSeconds(timeoutMs),
secure: opts?.secure ?? true,
allow_internet_access: opts?.allowInternetAccess ?? true,
network: opts?.network,
},
body,
signal: config.getSignal(opts?.requestTimeoutMs),
})

Expand Down
60 changes: 60 additions & 0 deletions packages/js-sdk/tests/sandbox/autoResume.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import { afterAll, afterEach, beforeAll, describe, expect, test } from 'vitest'

import { http, HttpResponse } from 'msw'
import { setupServer } from 'msw/node'

import { Sandbox } from '../../src'
import { apiUrl } from '../setup'

const templateId = 'test-template'
const sandboxResponse = {
templateID: templateId,
sandboxID: 'sandbox-123',
clientID: 'client-123',
envdVersion: '0.2.4',
envdAccessToken: 'envd-access-token',
trafficAccessToken: null,
domain: 'e2b.app',
}

let lastBody: Record<string, unknown> | undefined

const server = setupServer(
http.post(apiUrl('/sandboxes'), async ({ request }) => {
lastBody = (await request.clone().json()) as Record<string, unknown>
return HttpResponse.json(sandboxResponse, { status: 201 })
})
)

describe('Sandbox.create autoResume', () => {
beforeAll(() => server.listen({ onUnhandledRequest: 'error' }))
afterAll(() => server.close())
afterEach(() => {
lastBody = undefined
server.resetHandlers()
})

test('sends autoResume when provided', async () => {
await Sandbox.create(templateId, {
apiKey: 'test-api-key',
autoResume: { policy: 'any' },
apiUrl: apiUrl(''),
debug: false,
})

expect(lastBody?.autoResume).toEqual({ policy: 'any' })
})

test('omits autoResume when not provided', async () => {
await Sandbox.create(templateId, {
apiKey: 'test-api-key',
apiUrl: apiUrl(''),
debug: false,
})

expect(lastBody).toBeDefined()
expect(Object.prototype.hasOwnProperty.call(lastBody, 'autoResume')).toBe(
false
)
})
})
9 changes: 9 additions & 0 deletions packages/python-sdk/e2b/api/client/models/new_sandbox.py

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

16 changes: 15 additions & 1 deletion packages/python-sdk/e2b/sandbox/sandbox_api.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from dataclasses import dataclass
from datetime import datetime
from typing import Any, Dict, List, Optional, TypedDict, Union
from typing import Any, Dict, List, Literal, Optional, TypedDict, Union

from typing_extensions import NotRequired, Unpack

Expand Down Expand Up @@ -76,6 +76,20 @@ class SandboxNetworkOpts(TypedDict):
"""


SandboxAutoResumePolicy = Literal["any", "off"]


class SandboxAutoResumeConfig(TypedDict):
"""
Auto-resume configuration for paused sandboxes.
"""

policy: NotRequired[SandboxAutoResumePolicy]
"""
Auto-resume policy for paused sandboxes. Default is "off".
"""


@dataclass
class SandboxInfo:
"""Information about a sandbox."""
Expand Down
15 changes: 14 additions & 1 deletion packages/python-sdk/e2b/sandbox_async/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,12 @@
from e2b.envd.versions import ENVD_DEBUG_FALLBACK
from e2b.exceptions import SandboxException, format_request_timeout_error
from e2b.sandbox.main import SandboxOpts
from e2b.sandbox.sandbox_api import McpServer, SandboxMetrics, SandboxNetworkOpts
from e2b.sandbox.sandbox_api import (
McpServer,
SandboxAutoResumeConfig,
SandboxMetrics,
SandboxNetworkOpts,
)
from e2b.sandbox.utils import class_method_variant
from e2b.sandbox_async.commands.command import Commands
from e2b.sandbox_async.commands.pty import Pty
Expand Down Expand Up @@ -162,6 +167,7 @@ async def create(
allow_internet_access: bool = True,
mcp: Optional[McpServer] = None,
network: Optional[SandboxNetworkOpts] = None,
auto_resume: Optional[SandboxAutoResumeConfig] = None,
**opts: Unpack[ApiParams],
) -> Self:
"""
Expand All @@ -177,6 +183,7 @@ async def create(
:param allow_internet_access: Allow sandbox to access the internet, defaults to `True`. If set to `False`, it works the same as setting network `deny_out` to `[0.0.0.0/0]`.
:param mcp: MCP server to enable in the sandbox
:param network: Sandbox network configuration
:param auto_resume: Auto-resume configuration for paused sandboxes. Use `{"policy": "any" | "off"}` (default is "off"). Set to `{"policy": "any"}` to allow any request, or omit/`{"policy": "off"}` to disable.

:return: A Sandbox instance for the new sandbox

Expand All @@ -191,6 +198,7 @@ async def create(
template=template,
timeout=timeout,
auto_pause=False,
auto_resume=auto_resume,
metadata=metadata,
envs=envs,
secure=secure,
Expand Down Expand Up @@ -527,6 +535,7 @@ async def beta_create(
secure: bool = True,
allow_internet_access: bool = True,
mcp: Optional[McpServer] = None,
auto_resume: Optional[SandboxAutoResumeConfig] = None,
**opts: Unpack[ApiParams],
) -> Self:
"""
Expand All @@ -544,6 +553,7 @@ async def beta_create(
:param secure: Envd is secured with access token and cannot be used without it, defaults to `True`.
:param allow_internet_access: Allow sandbox to access the internet, defaults to `True`.
:param mcp: MCP server to enable in the sandbox
:param auto_resume: Auto-resume configuration for paused sandboxes. Use `{"policy": "any"}` to allow any request. Omit or use `{"policy": "off"}` to disable auto-resume.

:return: A Sandbox instance for the new sandbox

Expand All @@ -559,6 +569,7 @@ async def beta_create(
template=template,
timeout=timeout,
auto_pause=auto_pause,
auto_resume=auto_resume,
metadata=metadata,
envs=envs,
secure=secure,
Expand Down Expand Up @@ -680,6 +691,7 @@ async def _create(
template: Optional[str],
timeout: Optional[int],
auto_pause: bool,
auto_resume: Optional[SandboxAutoResumeConfig],
allow_internet_access: bool,
metadata: Optional[Dict[str, str]],
envs: Optional[Dict[str, str]],
Expand All @@ -702,6 +714,7 @@ async def _create(
template=template or cls.default_template,
timeout=timeout or cls.default_sandbox_timeout,
auto_pause=auto_pause,
auto_resume=auto_resume,
metadata=metadata,
env_vars=envs,
secure=secure,
Expand Down
3 changes: 3 additions & 0 deletions packages/python-sdk/e2b/sandbox_async/sandbox_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
from e2b.sandbox.main import SandboxBase
from e2b.sandbox.sandbox_api import (
McpServer,
SandboxAutoResumeConfig,
SandboxInfo,
SandboxMetrics,
SandboxNetworkOpts,
Expand Down Expand Up @@ -153,6 +154,7 @@ async def _create_sandbox(
template: str,
timeout: int,
auto_pause: bool,
auto_resume: Optional[SandboxAutoResumeConfig],
allow_internet_access: bool,
metadata: Optional[Dict[str, str]],
env_vars: Optional[Dict[str, str]],
Expand All @@ -168,6 +170,7 @@ async def _create_sandbox(
body=NewSandbox(
template_id=template,
auto_pause=auto_pause,
auto_resume=auto_resume,
metadata=metadata or {},
timeout=timeout,
env_vars=env_vars or {},
Expand Down
Loading
Loading