> 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.5.1/nemo-gym/nemo_gym/sandbox/providers/openshell/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.openshell OpenShell sandbox provider package. ## Submodules * **[`nemo_gym.sandbox.providers.openshell.provider`](/nemo/gym/nemo-gym/nemo_gym/sandbox/providers/openshell/provider)** ## Package Contents ### Classes | Name | Description | | --------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------- | | [`OpenShellConnectionConfig`](#nemo_gym-sandbox-providers-openshell-provider-OpenShellConnectionConfig) | Gateway connection settings. Defaults target a local plaintext gateway (deploy/docker compose). | | [`OpenShellCreateConfig`](#nemo_gym-sandbox-providers-openshell-provider-OpenShellCreateConfig) | - | | [`OpenShellCreateError`](#nemo_gym-sandbox-providers-openshell-provider-OpenShellCreateError) | Raised when the OpenShell gateway cannot create a sandbox. | | [`OpenShellCreateVerificationError`](#nemo_gym-sandbox-providers-openshell-provider-OpenShellCreateVerificationError) | Raised when a new sandbox fails its readiness probe. | | [`OpenShellExecConfig`](#nemo_gym-sandbox-providers-openshell-provider-OpenShellExecConfig) | - | | [`OpenShellOperationsConfig`](#nemo_gym-sandbox-providers-openshell-provider-OpenShellOperationsConfig) | - | | [`OpenShellProbeConfig`](#nemo_gym-sandbox-providers-openshell-provider-OpenShellProbeConfig) | - | | [`OpenShellProvider`](#nemo_gym-sandbox-providers-openshell-provider-OpenShellProvider) | Sandbox provider backed by an OpenShell gateway's gRPC control plane. | | [`OpenShellProviderOptions`](#nemo_gym-sandbox-providers-openshell-provider-OpenShellProviderOptions) | Validated per-sandbox options carried in `SandboxSpec.provider_options`. | ### API ```python class nemo_gym.sandbox.providers.openshell.OpenShellConnectionConfig( endpoint: str = 'localhost:8080', workspace: str = 'default', bearer_token: str | None = None, tls_ca_path: str | None = None, tls_cert_path: str | None = None, tls_key_path: str | None = None, request_timeout_s: float = 30.0 ) ``` Dataclass Gateway connection settings. Defaults target a local plaintext gateway (deploy/docker compose). **`bearer_token`** `str | None = None` --- **`endpoint`** `str = 'localhost:8080'` --- **`request_timeout_s`** `float = 30.0` --- **`tls_ca_path`** `str | None = None` --- **`tls_cert_path`** `str | None = None` --- **`tls_key_path`** `str | None = None` --- **`workspace`** `str = 'default'` --- ```python nemo_gym.sandbox.providers.openshell.OpenShellConnectionConfig.__post_init__() -> None ``` ```python class nemo_gym.sandbox.providers.openshell.OpenShellCreateConfig( ready_timeout_s: float = 300, poll_interval_s: float = 1.0, retries: int = 2, retry_delay_s: float = 1.0, retry_max_delay_s: float = 30.0 ) ``` Dataclass **`poll_interval_s`** `float = 1.0` --- **`ready_timeout_s`** `float = 300` --- **`retries`** `int = 2` --- **`retry_delay_s`** `float = 1.0` --- **`retry_max_delay_s`** `float = 30.0` --- ```python nemo_gym.sandbox.providers.openshell.OpenShellCreateConfig.__post_init__() -> None ``` ```python class nemo_gym.sandbox.providers.openshell.OpenShellCreateError() ``` **Bases:** [SandboxCreateError](/nemo/gym/nemo-gym/nemo_gym/sandbox/providers/base#nemo_gym-sandbox-providers-base-SandboxCreateError) Raised when the OpenShell gateway cannot create a sandbox. ```python class nemo_gym.sandbox.providers.openshell.OpenShellCreateVerificationError() ``` **Bases:** [SandboxCreateVerificationError](/nemo/gym/nemo-gym/nemo_gym/sandbox/providers/base#nemo_gym-sandbox-providers-base-SandboxCreateVerificationError) Raised when a new sandbox fails its readiness probe. ```python class nemo_gym.sandbox.providers.openshell.OpenShellExecConfig( default_timeout_s: float | None = 180, concurrency: int = 32, exec_shell: str = '/bin/sh', upload_chunk_bytes: int = DEFAULT_UPLOAD_CHUNK_BYTES ) ``` Dataclass **`concurrency`** `int = 32` --- **`default_timeout_s`** `float | None = 180` --- **`exec_shell`** `str = '/bin/sh'` --- **`upload_chunk_bytes`** `int = DEFAULT_UPLOAD_CHUNK_BYTES` --- ```python nemo_gym.sandbox.providers.openshell.OpenShellExecConfig.__post_init__() -> None ``` ```python class nemo_gym.sandbox.providers.openshell.OpenShellOperationsConfig( close_wait_deleted: bool = True, close_timeout_s: float = 60, poll_interval_s: float = 1.0 ) ``` Dataclass **`close_timeout_s`** `float = 60` --- **`close_wait_deleted`** `bool = True` --- **`poll_interval_s`** `float = 1.0` --- ```python nemo_gym.sandbox.providers.openshell.OpenShellOperationsConfig.__post_init__() -> None ``` ```python class nemo_gym.sandbox.providers.openshell.OpenShellProbeConfig( command: str | None = READY_PROBE_COMMAND, expected_stdout: str | None = READY_PROBE_EXPECTED, timeout_s: int = 30, deadline_s: float | None = 60, stable_count: int = 1, stable_delay_s: float = 1.0 ) ``` Dataclass **`command`** `str | None = READY_PROBE_COMMAND` --- **`deadline_s`** `float | None = 60` --- **`expected_stdout`** `str | None = READY_PROBE_EXPECTED` --- **`stable_count`** `int = 1` --- **`stable_delay_s`** `float = 1.0` --- **`timeout_s`** `int = 30` --- ```python nemo_gym.sandbox.providers.openshell.OpenShellProbeConfig.__post_init__() -> None ``` ```python class nemo_gym.sandbox.providers.openshell.OpenShellProvider( connection: nemo_gym.sandbox.providers.openshell.provider.OpenShellConnectionConfig | collections.abc.Mapping[str, typing.Any] | None = None, create: nemo_gym.sandbox.providers.openshell.provider.OpenShellCreateConfig | collections.abc.Mapping[str, typing.Any] | None = None, exec: nemo_gym.sandbox.providers.openshell.provider.OpenShellExecConfig | collections.abc.Mapping[str, typing.Any] | None = None, probe: nemo_gym.sandbox.providers.openshell.provider.OpenShellProbeConfig | collections.abc.Mapping[str, typing.Any] | None = None, operations: nemo_gym.sandbox.providers.openshell.provider.OpenShellOperationsConfig | collections.abc.Mapping[str, typing.Any] | None = None ) ``` Sandbox provider backed by an OpenShell gateway's gRPC control plane. **`_connection`** --- **`_create_config`** `= _coerce_config(create, OpenShellCreateConfig)` --- **`_exec_config`** `= _coerce_config(exec, OpenShellExecConfig)` --- **`_operations`** --- **`_probe`** `= _coerce_config(probe, OpenShellProbeConfig)` --- **`_shared`** --- **`name`** `= 'openshell'` --- ```python nemo_gym.sandbox.providers.openshell.OpenShellProvider._build_policy( policy: str | collections.abc.Mapping[str, typing.Any] ) -> typing.Any ``` ```python nemo_gym.sandbox.providers.openshell.OpenShellProvider._build_sandbox_spec( spec: nemo_gym.sandbox.providers.base.SandboxSpec, image: str | None, options: nemo_gym.sandbox.providers.openshell.provider.OpenShellProviderOptions ) -> typing.Any ``` ```python nemo_gym.sandbox.providers.openshell.OpenShellProvider._call( func: typing.Any, args: typing.Any = (), kwargs: typing.Any = {} ) -> typing.Any ``` async ```python nemo_gym.sandbox.providers.openshell.OpenShellProvider._cleanup_failed_create_handle( handle: nemo_gym.sandbox.providers.base.SandboxHandle ) -> None ``` async ```python nemo_gym.sandbox.providers.openshell.OpenShellProvider._create_sandbox_with_retries( pb_spec: typing.Any, name: str, labels: dict[str, str] ) -> typing.Any ``` async Issue CreateSandbox, retrying transient gRPC failures with the same name. Retrying with the same name is safe: if an earlier attempt actually committed, the retry fails ALREADY\_EXISTS and the sandbox is recovered via GetSandbox. ```python nemo_gym.sandbox.providers.openshell.OpenShellProvider._verify_created_handle( handle: nemo_gym.sandbox.providers.base.SandboxHandle ) -> None ``` async Poll the readiness probe until it passes `stable_count` times or the deadline elapses. ```python nemo_gym.sandbox.providers.openshell.OpenShellProvider._wait_deleted( inst: nemo_gym.sandbox.providers.openshell.provider._OpenShellSandbox ) -> None ``` async Poll GetSandbox until NOT\_FOUND (transient RPC failures keep polling until the deadline). ```python nemo_gym.sandbox.providers.openshell.OpenShellProvider._wait_ready( handle: nemo_gym.sandbox.providers.base.SandboxHandle, timeout_s: int | float ) -> None ``` async Poll GetSandbox until READY, raising on the ERROR/DELETING phases or the deadline. ```python nemo_gym.sandbox.providers.openshell.OpenShellProvider.aclose() -> None ``` async Release the shared client/pool (closed for real when the last provider releases it). ```python nemo_gym.sandbox.providers.openshell.OpenShellProvider.close( handle: nemo_gym.sandbox.providers.base.SandboxHandle ) -> None ``` async Delete the sandbox (already-gone counts as success), then wait until it is fully gone. ```python nemo_gym.sandbox.providers.openshell.OpenShellProvider.create( spec: nemo_gym.sandbox.providers.base.SandboxSpec ) -> nemo_gym.sandbox.providers.base.SandboxHandle ``` async Create a sandbox through the gateway, wait for the READY phase, then probe exec readiness. `spec.image` is optional (the gateway's configured default image is used when unset). `spec.ttl_s` is not enforced (OpenShell sandboxes live until deleted) and only logs a warning. `spec.entrypoint` is unsupported: the OpenShell supervisor owns the sandbox entrypoint. `spec.provider_options` accepts `providers` (OpenShell credential-provider names), `policy` (a SandboxPolicy mapping or YAML path), and `template_resources` / `driver_config` (free-form driver passthrough Structs). A half-created sandbox is deleted on any failure. ```python nemo_gym.sandbox.providers.openshell.OpenShellProvider.download_file( handle: nemo_gym.sandbox.providers.base.SandboxHandle, source_path: str, target_path: pathlib.Path ) -> None ``` async Download one sandbox file via a base64 round-trip (binary-safe over the text exec stream). The whole file is buffered in memory (inflated 4/3 by base64), so this is intended for small-to-medium artifacts rather than large archives. ```python nemo_gym.sandbox.providers.openshell.OpenShellProvider.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, stdin: bytes | None = None ) -> nemo_gym.sandbox.providers.base.SandboxExecResult ``` async Run `<shell> -c <command>` through the gateway's streaming exec; never raises for command failure. The timeout is enforced by the gateway (`timeout_seconds`); the SDK extends its gRPC deadline past it. `user` is ignored with a warning: the OpenShell exec API has no user field, so commands run as the sandbox's default user. ```python nemo_gym.sandbox.providers.openshell.OpenShellProvider.status( handle: nemo_gym.sandbox.providers.base.SandboxHandle ) -> nemo_gym.sandbox.providers.base.SandboxStatus ``` async Sandbox phase via GetSandbox (missing -> STOPPED; RPC failure -> UNKNOWN). ```python nemo_gym.sandbox.providers.openshell.OpenShellProvider.upload_file( handle: nemo_gym.sandbox.providers.base.SandboxHandle, source_path: pathlib.Path, target_path: str ) -> None ``` async Upload one local file by streaming its bytes through exec stdin (creates the parent dir). Bytes are sent in `exec.upload_chunk_bytes` chunks because each chunk travels as a single gRPC message that must stay under the gateway's max decode size. ```python class nemo_gym.sandbox.providers.openshell.OpenShellProviderOptions( providers: list[str] = list(), policy: typing.Any | None = None, template_resources: dict[str, typing.Any] = dict(), driver_config: dict[str, typing.Any] = dict() ) ``` Dataclass Validated per-sandbox options carried in `SandboxSpec.provider_options`. **`driver_config`** `dict[str, Any] = field(default_factory=dict)` --- **`policy`** `Any | None = None` --- **`providers`** `list[str] = field(default_factory=list)` --- **`template_resources`** `dict[str, Any] = field(default_factory=dict)` --- ```python nemo_gym.sandbox.providers.openshell.OpenShellProviderOptions.from_mapping( options: collections.abc.Mapping[str, typing.Any] ) -> nemo_gym.sandbox.providers.openshell.provider.OpenShellProviderOptions ``` classmethod ## Docs - [nemo_gym.sandbox.providers.openshell.provider](https://docs.nvidia.com/nemo/gym/v0.5.1/nemo-gym/nemo_gym/sandbox/providers/openshell/provider.md)