> For clean Markdown of any page, append .md to the page URL. > For a complete documentation index, see https://docs.nvidia.com/nemo/gym/v0.6.0/nemo-gym/nemo_gym/sandbox/providers/opensandbox/llms.txt. > For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.nvidia.com/nemo/gym/_mcp/server. # nemo_gym.sandbox.providers.opensandbox OpenSandbox provider package. ## Submodules * **[`nemo_gym.sandbox.providers.opensandbox.cleanup_sandboxes`](/nemo/gym/nemo-gym/nemo_gym/sandbox/providers/opensandbox/cleanup_sandboxes)** * **[`nemo_gym.sandbox.providers.opensandbox.provider`](/nemo/gym/nemo-gym/nemo_gym/sandbox/providers/opensandbox/provider)** * **[`nemo_gym.sandbox.providers.opensandbox.pty`](/nemo/gym/nemo-gym/nemo_gym/sandbox/providers/opensandbox/pty)** * **[`nemo_gym.sandbox.providers.opensandbox.snapshots`](/nemo/gym/nemo-gym/nemo_gym/sandbox/providers/opensandbox/snapshots)** ## Package Contents ### Classes | Name | Description | | --------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------- | | [`OpenSandboxAttributionConfig`](#nemo_gym-sandbox-providers-opensandbox-provider-OpenSandboxAttributionConfig) | Job attribution merged into every sandbox's metadata (Kubernetes labels on the sandbox). | | [`OpenSandboxConnectionConfig`](#nemo_gym-sandbox-providers-opensandbox-provider-OpenSandboxConnectionConfig) | OpenSandbox server connection settings. | | [`OpenSandboxCreateConfig`](#nemo_gym-sandbox-providers-opensandbox-provider-OpenSandboxCreateConfig) | OpenSandbox create/reconnect retry settings. | | [`OpenSandboxCreateError`](#nemo_gym-sandbox-providers-opensandbox-provider-OpenSandboxCreateError) | Raised when OpenSandbox cannot create a sandbox. | | [`OpenSandboxCreateTimeoutError`](#nemo_gym-sandbox-providers-opensandbox-provider-OpenSandboxCreateTimeoutError) | Raised when OpenSandbox sandbox creation exceeds the client timeout. | | [`OpenSandboxCreateVerificationError`](#nemo_gym-sandbox-providers-opensandbox-provider-OpenSandboxCreateVerificationError) | Raised when a newly-created sandbox cannot execute a probe command. | | [`OpenSandboxOperationConfig`](#nemo_gym-sandbox-providers-opensandbox-provider-OpenSandboxOperationConfig) | Retry and timeout settings for SDK operations after create. | | [`OpenSandboxProbeConfig`](#nemo_gym-sandbox-providers-opensandbox-provider-OpenSandboxProbeConfig) | Post-create probe settings. | | [`OpenSandboxProvider`](#nemo_gym-sandbox-providers-opensandbox-provider-OpenSandboxProvider) | Provider backed by the OpenSandbox SDK/server API. | ### API ```python class nemo_gym.sandbox.providers.opensandbox.OpenSandboxAttributionConfig( enabled: bool = True, team: str | None = None, user: str | None = None, workload: str | None = None, run: str | None = None, key_prefix: str = DEFAULT_ATTRIBUTION_KEY_PREFIX ) ``` Dataclass Job attribution merged into every sandbox's metadata (Kubernetes labels on the sandbox). OpenSandbox propagates sandbox metadata as Kubernetes labels on the sandbox resources, so attribution is queryable both through the OpenSandbox list API and at the cluster level (e.g. `kubectl get pods -l nemo-gym.nvidia.com/team=my-team`). `key_prefix` namespaces the label keys (Kubernetes prefixed-key convention); set it to `""` for bare `team` / `user` / `workload` / `run` keys. Unset fields are auto-detected: `NEMO_GYM_TEAM` / `NEMO_GYM_USER` / `NEMO_GYM_WORKLOAD` environment variables first, then Slurm job env vars (`SLURM_JOB_ACCOUNT` / `SLURM_JOB_USER` / `SLURM_JOB_NAME`), then the OS login name for `user` (`root` is ignored) and the gym CLI's `NEMO_GYM_CONFIG_PATH` server instance name for `workload`. Fields that cannot be resolved are omitted. `run` scopes sandboxes to one launch of the creating process (`NEMO_GYM_RUN_ID`, else generated per process and logged) so a run's sandboxes can be listed and cleaned up exactly. Explicit `SandboxSpec.metadata` keys always take precedence over attribution keys. **`enabled`** `bool = True` --- **`key_prefix`** `str = DEFAULT_ATTRIBUTION_KEY_PREFIX` --- **`run`** `str | None = None` --- **`team`** `str | None = None` --- **`user`** `str | None = None` --- **`workload`** `str | None = None` --- ```python nemo_gym.sandbox.providers.opensandbox.OpenSandboxAttributionConfig.__post_init__() -> None ``` ```python class nemo_gym.sandbox.providers.opensandbox.OpenSandboxConnectionConfig( domain: str | None = None, api_key: str | None = None, protocol: str | None = None, request_timeout_s: int | None = None, use_server_proxy: bool = False, disable_connection_pooling: bool = False, keepalive_expiry_s: float | None = 3.0, max_keepalive_connections: int = 20, max_connections: int | None = 100, connect_retries: int = 2, transport_backend: str = 'aiohttp', tls_verify: bool = False ) ``` Dataclass OpenSandbox server connection settings. With the legacy httpx backend, `keepalive_expiry_s` must stay below the server's own keep-alive idle timeout (uvicorn defaults to 5s), or sockets are reused after the server has closed them; null falls back to the SDK's default transport only when certificate verification is enabled and pooling is not disabled. `transport_backend=aiohttp` uses Gym's global client and connector limits; provider-local pooling settings apply only to `transport_backend=httpx`. `tls_verify` applies to every connection the provider opens (SDK transport and PTY sockets) and is off by default; set it for endpoints whose certificate the client can verify. `domain` may carry its scheme (`https://sandbox.example`). The scheme is moved into `protocol` and takes precedence over a configured `protocol`, so every URL the provider builds itself (the PTY WebSocket target) agrees with the SDK's base URL; the SDK receives the host plus any path prefix (`sandbox.example:8080/prefix`). The SDK would accept a scheme in `domain` on its own, but the provider reads `protocol` directly, hence the normalization here. Only `scheme://host[:port][/path-prefix]` is accepted: a query string or fragment is a configuration error. **`api_key`** `str | None = None` --- **`connect_retries`** `int = 2` --- **`disable_connection_pooling`** `bool = False` --- **`domain`** `str | None = None` --- **`keepalive_expiry_s`** `float | None = 3.0` --- **`max_connections`** `int | None = 100` --- **`max_keepalive_connections`** `int = 20` --- **`protocol`** `str | None = None` --- **`request_timeout_s`** `int | None = None` --- **`tls_verify`** `bool = False` --- **`transport_backend`** `str = 'aiohttp'` --- **`use_server_proxy`** `bool = False` --- ```python nemo_gym.sandbox.providers.opensandbox.OpenSandboxConnectionConfig.__post_init__() -> None ``` ```python class nemo_gym.sandbox.providers.opensandbox.OpenSandboxCreateConfig( request_timeout_s: int | None = None, timeout_s: float | None = None, retries: int = 2, retry_delay_s: float = 5.0, retry_max_delay_s: float = 60.0, image_pull_policy: str | None = DEFAULT_IMAGE_PULL_POLICY, skip_health_check: bool = False, connect_attempt_timeout_s: float = 30.0, connect_poll_s: float = 2.0, renew_interval_s: float | None = None ) ``` Dataclass OpenSandbox create/reconnect retry settings. **`connect_attempt_timeout_s`** `float = 30.0` --- **`connect_poll_s`** `float = 2.0` --- **`image_pull_policy`** `str | None = DEFAULT_IMAGE_PULL_POLICY` --- **`renew_interval_s`** `float | None = None` --- **`request_timeout_s`** `int | None = None` --- **`retries`** `int = 2` --- **`retry_delay_s`** `float = 5.0` --- **`retry_max_delay_s`** `float = 60.0` --- **`skip_health_check`** `bool = False` --- **`timeout_s`** `float | None = None` --- ```python nemo_gym.sandbox.providers.opensandbox.OpenSandboxCreateConfig.__post_init__() -> None ``` ```python class nemo_gym.sandbox.providers.opensandbox.OpenSandboxCreateError() ``` **Bases:** [SandboxCreateError](/nemo/gym/nemo-gym/nemo_gym/sandbox/providers/base#nemo_gym-sandbox-providers-base-SandboxCreateError) Raised when OpenSandbox cannot create a sandbox. ```python class nemo_gym.sandbox.providers.opensandbox.OpenSandboxCreateTimeoutError() ``` **Bases:** [OpenSandboxCreateError](#nemo_gym-sandbox-providers-opensandbox-provider-OpenSandboxCreateError) Raised when OpenSandbox sandbox creation exceeds the client timeout. ```python class nemo_gym.sandbox.providers.opensandbox.OpenSandboxCreateVerificationError() ``` **Bases:** [SandboxCreateVerificationError](/nemo/gym/nemo-gym/nemo_gym/sandbox/providers/base#nemo_gym-sandbox-providers-base-SandboxCreateVerificationError) Raised when a newly-created sandbox cannot execute a probe command. ```python class nemo_gym.sandbox.providers.opensandbox.OpenSandboxOperationConfig( retries: int = 3, retry_delay_s: float = 1.0, retry_max_delay_s: float = 15.0, command_retries: int = 0, close_timeout_s: float | None = 30.0, pause_resume_timeout_s: float = 600.0, background_exec: bool = False, background_poll_initial_s: float = 0.25, background_poll_interval_s: float = 2.0, status_poll_timeout_s: float | None = 10.0 ) ``` Dataclass Retry and timeout settings for SDK operations after create. **`background_exec`** `bool = False` --- **`background_poll_initial_s`** `float = 0.25` --- **`background_poll_interval_s`** `float = 2.0` --- **`close_timeout_s`** `float | None = 30.0` --- **`command_retries`** `int = 0` --- **`pause_resume_timeout_s`** `float = 600.0` --- **`retries`** `int = 3` --- **`retry_delay_s`** `float = 1.0` --- **`retry_max_delay_s`** `float = 15.0` --- **`status_poll_timeout_s`** `float | None = 10.0` --- ```python nemo_gym.sandbox.providers.opensandbox.OpenSandboxOperationConfig.__post_init__() -> None ``` ```python class nemo_gym.sandbox.providers.opensandbox.OpenSandboxProbeConfig( command: str | None = 'printf nemo-gym-sandbox-re..., expected_stdout: str | None = 'nemo-gym-sandbox-ready', timeout_s: int = 30, deadline_s: float | None = None, stable_count: int = 1, stable_delay_s: float = 0.0, user: str | int | None = None ) ``` Dataclass Post-create probe settings. **`command`** `str | None = 'printf nemo-gym-sandbox-ready'` --- **`deadline_s`** `float | None = None` --- **`expected_stdout`** `str | None = 'nemo-gym-sandbox-ready'` --- **`stable_count`** `int = 1` --- **`stable_delay_s`** `float = 0.0` --- **`timeout_s`** `int = 30` --- **`user`** `str | int | None = None` --- ```python nemo_gym.sandbox.providers.opensandbox.OpenSandboxProbeConfig.__post_init__() -> None ``` ```python class nemo_gym.sandbox.providers.opensandbox.OpenSandboxProvider( connection: nemo_gym.sandbox.providers.opensandbox.provider.OpenSandboxConnectionConfig | collections.abc.Mapping[str, typing.Any] | None = None, create: nemo_gym.sandbox.providers.opensandbox.provider.OpenSandboxCreateConfig | collections.abc.Mapping[str, typing.Any] | None = None, probe: nemo_gym.sandbox.providers.opensandbox.provider.OpenSandboxProbeConfig | collections.abc.Mapping[str, typing.Any] | None = None, operations: nemo_gym.sandbox.providers.opensandbox.provider.OpenSandboxOperationConfig | collections.abc.Mapping[str, typing.Any] | None = None, attribution: nemo_gym.sandbox.providers.opensandbox.provider.OpenSandboxAttributionConfig | collections.abc.Mapping[str, typing.Any] | None = None, networking: nemo_gym.sandbox.providers.opensandbox.provider.OpenSandboxNetworkingConfig | collections.abc.Mapping[str, typing.Any] | None = None, shared_storage: nemo_gym.sandbox.providers.opensandbox.provider.OpenSandboxSharedStorageConfig | collections.abc.Mapping[str, typing.Any] | None = None, runtime_requirements: nemo_gym.sandbox.providers.opensandbox.provider.OpenSandboxRuntimeRequirementsConfig | collections.abc.Mapping[str, typing.Any] | None = None ) ``` Provider backed by the OpenSandbox SDK/server API. **`_attribution`** --- **`_connection`** --- **`_create`** `= _coerce_config(create, OpenSandboxCreateConfig)` --- **`_networking`** --- **`_operations`** --- **`_probe`** `= _coerce_config(probe, OpenSandboxProbeConfig)` --- **`_pty_sessions`** `set[Any] = set()` --- **`_renewals`** `dict[str, Task[None]] = {}` --- **`_runtime_requirements`** --- **`_shared_storage`** --- **`_transport`** `Any | None = None` --- **`name`** `= 'opensandbox'` --- ```python nemo_gym.sandbox.providers.opensandbox.OpenSandboxProvider._attribution_metadata() -> dict[str, str] ``` ```python nemo_gym.sandbox.providers.opensandbox.OpenSandboxProvider._await_sdk_call( awaitable: typing.Any, operation: str, sandbox_id: str, timeout_s: float | None ) -> typing.Any ``` async ```python nemo_gym.sandbox.providers.opensandbox.OpenSandboxProvider._await_sdk_operation( operation_factory: typing.Callable[[], typing.Awaitable[typing.Any]], operation: str, sandbox_id: str, timeout_s: float | None, retries: int | None = None, is_retryable: typing.Callable[[BaseException], bool] = _is_retryable_sdk_operation... ) -> typing.Any ``` async ```python nemo_gym.sandbox.providers.opensandbox.OpenSandboxProvider._build_transport() -> typing.Any ``` Use Gym's global HTTP pool, or the explicitly selected legacy backend. ```python nemo_gym.sandbox.providers.opensandbox.OpenSandboxProvider._cleanup_failed_create_handle( handle: nemo_gym.sandbox.providers.base.SandboxHandle ) -> None ``` async ```python nemo_gym.sandbox.providers.opensandbox.OpenSandboxProvider._command_retry_count() -> int ``` ```python nemo_gym.sandbox.providers.opensandbox.OpenSandboxProvider._connect_after_create( handle: nemo_gym.sandbox.providers.base.SandboxHandle, spec: nemo_gym.sandbox.providers.base.SandboxSpec ) -> nemo_gym.sandbox.providers.base.SandboxHandle ``` async Reconnect after SDK create so follow-up calls use a fresh SDK handle. ```python nemo_gym.sandbox.providers.opensandbox.OpenSandboxProvider._connection_config( request_timeout_s: int | float | None = None ) -> typing.Any ``` ```python nemo_gym.sandbox.providers.opensandbox.OpenSandboxProvider._create_once( spec: nemo_gym.sandbox.providers.base.SandboxSpec ) -> nemo_gym.sandbox.providers.base.SandboxHandle ``` async Create a sandbox through `opensandbox.Sandbox.create`. ```python nemo_gym.sandbox.providers.opensandbox.OpenSandboxProvider._create_with_retries( spec: nemo_gym.sandbox.providers.base.SandboxSpec ) -> nemo_gym.sandbox.providers.base.SandboxHandle ``` async ```python nemo_gym.sandbox.providers.opensandbox.OpenSandboxProvider._exec( handle: nemo_gym.sandbox.providers.base.SandboxHandle, command: str, cwd: str | None = None, env: dict[str, str] | None = None, timeout_s: int | float | None = None, user: str | int | None = None, retries: int | None = None ) -> nemo_gym.sandbox.providers.base.SandboxExecResult ``` async Run a command inside an OpenSandbox sandbox. ```python nemo_gym.sandbox.providers.opensandbox.OpenSandboxProvider._exec_background( handle: nemo_gym.sandbox.providers.base.SandboxHandle, command: str, opts_kwargs: dict[str, typing.Any], sdk_timeout_s: float | None, total_timeout_s: int | float | None, retries: int ) -> nemo_gym.sandbox.providers.base.SandboxExecResult ``` async Run a command as a background execution polled via short requests. The logs endpoint returns one combined stream, so unlike the foreground path `stdout` carries both streams and `stderr` is set only when the sandbox itself reports an error. ```python nemo_gym.sandbox.providers.opensandbox.OpenSandboxProvider._get_transport() -> typing.Any ``` Return the provider-owned shared transport, building it on first use. ```python nemo_gym.sandbox.providers.opensandbox.OpenSandboxProvider._oom_death_notice( handle: nemo_gym.sandbox.providers.base.SandboxHandle, any_death: bool = False ) -> str | None ``` async Briefly poll the sandbox status; describe an OOM kill, else None. With `any_death` every terminal state is reported, not just an OOM kill — for callers that need to know whether the sandbox is gone at all, not specifically why. When the backend stops answering it usually takes the control plane a moment to record why, so poll for up to 5s before giving up. ```python nemo_gym.sandbox.providers.opensandbox.OpenSandboxProvider._pty_http_client() -> typing.Any ``` Return the aiohttp client for one PTY session (same `tls_verify` as the SDK transport). ```python nemo_gym.sandbox.providers.opensandbox.OpenSandboxProvider._pty_session_missing( base_url: str, headers: dict[str, str], session_id: str, request_timeout_s: float | None ) -> bool ``` async True only when execd itself reports the PTY session does not exist. A proxy 404 (route not registered yet) lacks execd's error code, and a failed check is treated as unknown so the attach proceeds as before. ```python nemo_gym.sandbox.providers.opensandbox.OpenSandboxProvider._pty_target( handle: nemo_gym.sandbox.providers.base.SandboxHandle ) -> tuple[str, dict[str, str], float | None] ``` async Resolve the sandbox's execd base URL, headers and request timeout. ```python nemo_gym.sandbox.providers.opensandbox.OpenSandboxProvider._read_file( handle: nemo_gym.sandbox.providers.base.SandboxHandle, source_path: str ) -> bytes ``` async Read one file from an OpenSandbox sandbox. ```python nemo_gym.sandbox.providers.opensandbox.OpenSandboxProvider._resolve_extensions( extensions: collections.abc.Mapping[str, str] ) -> dict[str, str] ``` Add the configured default image pull policy to SDK create extensions. ```python nemo_gym.sandbox.providers.opensandbox.OpenSandboxProvider._retire_closed_pty_sessions() -> None ``` async Release sessions that ended on their own; their aiohttp client is only freed by `close()`. Called from create/attach so the tracking set cannot grow without bound. ```python nemo_gym.sandbox.providers.opensandbox.OpenSandboxProvider._start_renewal( handle: nemo_gym.sandbox.providers.base.SandboxHandle, ttl_s: int | float ) -> None ``` ```python nemo_gym.sandbox.providers.opensandbox.OpenSandboxProvider._stop_renewal( sandbox_id: str ) -> BaseException | None ``` async ```python nemo_gym.sandbox.providers.opensandbox.OpenSandboxProvider._submit_command( operation_factory: typing.Callable[[], typing.Awaitable[typing.Any]], operation: str, sandbox_id: str, timeout_s: float | None, retries: int ) -> typing.Any ``` async Retry backend-connect 502s that `command_retries` deliberately skips. A proxy 502 is a TCP-connect failure: the command never reached execd, so retrying under `operations.retries` cannot double-run it (unlike a real command failure). When that budget is exhausted the backend is dead, so raise a typed error and fail fast instead of retrying for hours. ```python nemo_gym.sandbox.providers.opensandbox.OpenSandboxProvider._verify_created_handle( handle: nemo_gym.sandbox.providers.base.SandboxHandle ) -> None ``` async ```python nemo_gym.sandbox.providers.opensandbox.OpenSandboxProvider._write_file( handle: nemo_gym.sandbox.providers.base.SandboxHandle, target_path: str, data: str | bytes ) -> None ``` async Write one file into an OpenSandbox sandbox. ```python nemo_gym.sandbox.providers.opensandbox.OpenSandboxProvider.aclose() -> None ``` async Close provider-owned resources. ```python nemo_gym.sandbox.providers.opensandbox.OpenSandboxProvider.attach_pty( handle: nemo_gym.sandbox.providers.base.SandboxHandle, session_id: str, takeover: bool = True, since: int | None = None ) -> nemo_gym.sandbox.providers.base.SandboxPtySession ``` async Re-attach to an existing execd PTY session by id. ```python nemo_gym.sandbox.providers.opensandbox.OpenSandboxProvider.close( handle: nemo_gym.sandbox.providers.base.SandboxHandle ) -> None ``` async Terminate the sandbox and close local SDK resources. ```python nemo_gym.sandbox.providers.opensandbox.OpenSandboxProvider.configure_runtime( handle: nemo_gym.sandbox.providers.base.SandboxHandle, cap_add: tuple[str, ...], shm_size: int | None ) -> None ``` async Probe capabilities and verify the shared memory allocated at creation. ```python nemo_gym.sandbox.providers.opensandbox.OpenSandboxProvider.connect( descriptor: collections.abc.Mapping[str, typing.Any] ) -> nemo_gym.sandbox.providers.base.SandboxHandle ``` async Rebuild a live handle from an OpenSandbox sandbox id via the SDK. Running sandboxes are health-checked unless the caller opts out. A paused sandbox has no exec daemon to check; resume rebuilds its endpoints and performs the health check instead. ```python nemo_gym.sandbox.providers.opensandbox.OpenSandboxProvider.create( spec: nemo_gym.sandbox.providers.base.SandboxSpec ) -> nemo_gym.sandbox.providers.base.SandboxHandle ``` async Create one sandbox through the configured OpenSandbox path. Job attribution keys (`team` / `user` / `workload` / `run`) are merged into the spec's metadata (explicit spec keys win) so every sandbox is attributable via its labels. ```python nemo_gym.sandbox.providers.opensandbox.OpenSandboxProvider.create_pty( handle: nemo_gym.sandbox.providers.base.SandboxHandle, spec: nemo_gym.sandbox.providers.base.SandboxPtySpec ) -> nemo_gym.sandbox.providers.base.SandboxPtySession ``` async Open an interactive execd PTY session inside a sandbox. ```python nemo_gym.sandbox.providers.opensandbox.OpenSandboxProvider.download_file( handle: nemo_gym.sandbox.providers.base.SandboxHandle, source_path: str, target_path: pathlib.Path ) -> None ``` async Download one file from an OpenSandbox sandbox. ```python nemo_gym.sandbox.providers.opensandbox.OpenSandboxProvider.endpoint( handle: nemo_gym.sandbox.providers.base.SandboxHandle, port: int ) -> nemo_gym.sandbox.providers.base.SandboxEndpoint ``` async Resolve one client-reachable direct or server-proxied service URL. ```python nemo_gym.sandbox.providers.opensandbox.OpenSandboxProvider.exec( handle: nemo_gym.sandbox.providers.base.SandboxHandle, command: str, cwd: str | None = None, env: dict[str, str] | None = None, timeout_s: int | float | None = None, user: str | int | None = None ) -> nemo_gym.sandbox.providers.base.SandboxExecResult ``` async Run a command inside an OpenSandbox sandbox. ```python nemo_gym.sandbox.providers.opensandbox.OpenSandboxProvider.exec_with_background_services( handle: nemo_gym.sandbox.providers.base.SandboxHandle, command: str, cwd: str | None = None, timeout_s: int | float | None = None ) -> nemo_gym.sandbox.providers.base.SandboxExecResult ``` async Preserve background services that redirect their stdout and stderr. ```python nemo_gym.sandbox.providers.opensandbox.OpenSandboxProvider.forward_ports( handle: nemo_gym.sandbox.providers.base.SandboxHandle, target_address: str, ports: tuple[int, ...], ready_file: str ) -> None ``` async Run loopback listeners in a foreground command owned by the collection. ```python nemo_gym.sandbox.providers.opensandbox.OpenSandboxProvider.network_address( handle: nemo_gym.sandbox.providers.base.SandboxHandle ) -> str ``` async Resolve a direct container IP, independently of client proxy mode. ```python nemo_gym.sandbox.providers.opensandbox.OpenSandboxProvider.pause( handle: nemo_gym.sandbox.providers.base.SandboxHandle ) -> None ``` async Pause a sandbox and wait until it reports paused. Local PTY clients are detached first, while execd can still answer the close handshake; server sessions are never deleted, so they remain attachable if the pause request fails. After resume, the Kubernetes backend has replaced the runtime (open a new PTY); the Docker backend thawed it (re-attach by id). ```python nemo_gym.sandbox.providers.opensandbox.OpenSandboxProvider.resume( handle: nemo_gym.sandbox.providers.base.SandboxHandle ) -> None ``` async Resume a paused sandbox and rebuild its SDK clients and endpoints. One `pause_resume_timeout_s` deadline covers the request, endpoint rebuild and readiness check. On timeout the server-side state is unknown: reconnect and check `status()` before retrying. See `pause()` for what happens to PTY sessions. ```python nemo_gym.sandbox.providers.opensandbox.OpenSandboxProvider.serialize_handle( handle: nemo_gym.sandbox.providers.base.SandboxHandle, scope: str | None = None ) -> dict[str, typing.Any] ``` async Return a descriptor for reattaching to this sandbox by id. OpenSandbox sandboxes are reachable by id from any process that has the connection config, so the id alone is enough to reconnect and no sandbox server is needed to share one. `scope` is ignored: OpenSandbox has no lease concept of its own. ```python nemo_gym.sandbox.providers.opensandbox.OpenSandboxProvider.set_hosts( handle: nemo_gym.sandbox.providers.base.SandboxHandle, hosts: collections.abc.Mapping[str, str] ) -> None ``` async Append validated peer aliases to the sandbox hosts file. ```python nemo_gym.sandbox.providers.opensandbox.OpenSandboxProvider.shared_volume_metadata() -> dict[str, str] ``` Return placement metadata required by the configured shared storage. ```python nemo_gym.sandbox.providers.opensandbox.OpenSandboxProvider.shared_volume_options( source: str | None, target: str, read_only: bool = False ) -> dict[str, typing.Any] ``` Mount a project directory, or the shared root for bootstrap when source is None. ```python nemo_gym.sandbox.providers.opensandbox.OpenSandboxProvider.status( handle: nemo_gym.sandbox.providers.base.SandboxHandle ) -> nemo_gym.sandbox.providers.base.SandboxStatus ``` async Return the current OpenSandbox lifecycle status. ```python nemo_gym.sandbox.providers.opensandbox.OpenSandboxProvider.upload_file( handle: nemo_gym.sandbox.providers.base.SandboxHandle, source_path: pathlib.Path, target_path: str ) -> None ``` async Upload one local file into an OpenSandbox sandbox. ```python nemo_gym.sandbox.providers.opensandbox.OpenSandboxProvider.validate_networking() -> None ``` Require explicit deployment support for inter-sandbox networking. ```python nemo_gym.sandbox.providers.opensandbox.OpenSandboxProvider.validate_port_forwarding() -> None ``` Require explicit deployment support for loopback TCP listeners. ```python nemo_gym.sandbox.providers.opensandbox.OpenSandboxProvider.validate_runtime_requirements( cap_add: tuple[str, ...], shm_size: int | None ) -> dict[str, str] ``` Reject requirements without an operator-configured implementation. ## Docs - [nemo_gym.sandbox.providers.opensandbox.cleanup_sandboxes](https://docs.nvidia.com/nemo/gym/v0.6.0/nemo-gym/nemo_gym/sandbox/providers/opensandbox/cleanup_sandboxes.md) - [nemo_gym.sandbox.providers.opensandbox.provider](https://docs.nvidia.com/nemo/gym/v0.6.0/nemo-gym/nemo_gym/sandbox/providers/opensandbox/provider.md) - [nemo_gym.sandbox.providers.opensandbox.pty](https://docs.nvidia.com/nemo/gym/v0.6.0/nemo-gym/nemo_gym/sandbox/providers/opensandbox/pty.md) - [nemo_gym.sandbox.providers.opensandbox.snapshots](https://docs.nvidia.com/nemo/gym/v0.6.0/nemo-gym/nemo_gym/sandbox/providers/opensandbox/snapshots.md)