nemo_gym.sandbox.providers.base

View as Markdown

Provider-facing sandbox protocol.

Module Contents

Classes

NameDescription
ConnectableProviderOptional capability: rebuild a handle in another process from a descriptor.
SandboxCreateErrorRaised when a provider cannot create a sandbox.
SandboxCreateVerificationErrorRaised when a newly-created sandbox fails provider readiness checks.
SandboxEndpointProvider-neutral route to a long-lived service inside a sandbox.
SandboxExecResultProvider-neutral process execution result.
SandboxHandleProvider-neutral handle to a created sandbox.
SandboxProviderRuntime/infra provider contract used by the public sandbox API.
SandboxPtyErrorRaised when a PTY session fails outside normal process exit.
SandboxPtySessionOne live interactive terminal. Async context manager; exit closes it.
SandboxPtySpecInteractive PTY session request.
SandboxResourcesProvider-neutral resource request.
SandboxSpecSandbox creation request.
SandboxStatusProvider-neutral sandbox lifecycle status.
SupportsSandboxEndpointOptional provider capability for resolving declared service ports.
SupportsSandboxPtyOptional provider capability: interactive PTY sessions.
SupportsSandboxPtyAttachOptional provider capability: re-attach to a PTY session by id.

Data

ExecResult

API

class nemo_gym.sandbox.providers.base.ConnectableProvider()
Protocol

Optional capability: rebuild a handle in another process from a descriptor.

Providers whose sandboxes are reachable by id (external control plane, e.g. OpenSandbox and Fargate, and the sandbox server’s remote provider) implement this. A provider that does not implement it can only be shared by fronting it with a sandbox server. Membership is checked with isinstance because the protocol is runtime_checkable.

nemo_gym.sandbox.providers.base.ConnectableProvider.connect(
descriptor: collections.abc.Mapping[str, typing.Any]
) -> nemo_gym.sandbox.providers.base.SandboxHandle
async

Rebuild a live handle in this process from a descriptor.

nemo_gym.sandbox.providers.base.ConnectableProvider.serialize_handle(
handle: nemo_gym.sandbox.providers.base.SandboxHandle,
scope: str | None = None
) -> dict[str, typing.Any]
async

Return a JSON-serializable descriptor that connect can rebuild a handle from. scope is honored by providers that mint leases (the remote provider) and ignored by the rest.

class nemo_gym.sandbox.providers.base.SandboxCreateError()

Bases: RuntimeError

Raised when a provider cannot create a sandbox.

class nemo_gym.sandbox.providers.base.SandboxCreateVerificationError()

Bases: SandboxCreateError

Raised when a newly-created sandbox fails provider readiness checks.

class nemo_gym.sandbox.providers.base.SandboxEndpoint(
endpoint: str,
headers: dict[str, str] = dict()
)
Dataclass

Provider-neutral route to a long-lived service inside a sandbox.

endpoint is an absolute URL. headers carries provider-required authentication or routing headers without exposing the provider’s opaque handle to callers.

endpoint
str
headers
dict[str, str] = field(default_factory=dict)
nemo_gym.sandbox.providers.base.SandboxEndpoint.__post_init__() -> None
class nemo_gym.sandbox.providers.base.SandboxExecResult(
stdout: str | None,
stderr: str | None,
return_code: int,
error_type: str | None = None
)
Dataclass

Provider-neutral process execution result.

return_code is the process exit code when the sandbox actually ran the command. Providers may use a non-process sentinel with error_type set when the sandbox runtime reports an execution failure without a process exit code.

error_type
str | None = None
return_code
int
stderr
str | None
stdout
str | None
class nemo_gym.sandbox.providers.base.SandboxHandle(
sandbox_id: str,
provider_name: str,
raw: typing.Any
)
Dataclass

Provider-neutral handle to a created sandbox.

raw is provider-owned opaque state. Public code should pass it back to the provider through this handle rather than inspecting or mutating it directly.

provider_name
str
sandbox_id
str
class nemo_gym.sandbox.providers.base.SandboxProvider()
Protocol

Runtime/infra provider contract used by the public sandbox API.

name
str
nemo_gym.sandbox.providers.base.SandboxProvider.aclose() -> None
async

Close provider-scoped resources such as SDK clients.

nemo_gym.sandbox.providers.base.SandboxProvider.close(
handle: nemo_gym.sandbox.providers.base.SandboxHandle
) -> None
async

End the sandbox lifecycle and close provider resources for it.

nemo_gym.sandbox.providers.base.SandboxProvider.create(
spec: nemo_gym.sandbox.providers.base.SandboxSpec
) -> nemo_gym.sandbox.providers.base.SandboxHandle
async

Create a ready sandbox and return a provider-neutral handle.

Providers must return only after the sandbox is healthy enough to run commands and transfer files. If the sandbox cannot become ready before the configured timeout, providers should raise SandboxCreateError or a provider-specific subclass.

nemo_gym.sandbox.providers.base.SandboxProvider.download_file(
handle: nemo_gym.sandbox.providers.base.SandboxHandle,
source_path: str,
target_path: pathlib.Path
) -> None
async

Download one sandbox file to the local filesystem.

nemo_gym.sandbox.providers.base.SandboxProvider.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 a sandbox.

nemo_gym.sandbox.providers.base.SandboxProvider.status(
handle: nemo_gym.sandbox.providers.base.SandboxHandle
) -> nemo_gym.sandbox.providers.base.SandboxStatus
async

Return the current sandbox lifecycle status.

nemo_gym.sandbox.providers.base.SandboxProvider.upload_file(
handle: nemo_gym.sandbox.providers.base.SandboxHandle,
source_path: pathlib.Path,
target_path: str
) -> None
async

Upload one local file into a sandbox.

class nemo_gym.sandbox.providers.base.SandboxPtyError()

Bases: RuntimeError

Raised when a PTY session fails outside normal process exit.

class nemo_gym.sandbox.providers.base.SandboxPtySession()
Protocol

One live interactive terminal. Async context manager; exit closes it.

closed
bool

Whether close() has run; a closed session cannot run commands.

mode
str | None

"pty" or "pipe" once connected, None before that. Only pipe mode splits stderr; in PTY mode all output arrives through read().

session_id
str
async
nemo_gym.sandbox.providers.base.SandboxPtySession.__aexit__(
exc_type: typing.Any,
exc_val: typing.Any,
exc_tb: typing.Any
) -> None
async
nemo_gym.sandbox.providers.base.SandboxPtySession.__aiter__() -> collections.abc.AsyncIterator[bytes]

Yield output chunks until EOF.

nemo_gym.sandbox.providers.base.SandboxPtySession.close() -> None
async

Idempotent: release local resources; a session this client created is also ended, while an attached one is merely detached and lives on for its owner.

nemo_gym.sandbox.providers.base.SandboxPtySession.read(
timeout_s: float | None = None
) -> bytes
async

Return the next output chunk (all terminal output in PTY mode; stdout only in pipe mode). b"" means the process exited and the stream is drained. Raises TimeoutError on timeout and SandboxPtyError if the session died without exiting.

nemo_gym.sandbox.providers.base.SandboxPtySession.read_stderr(
timeout_s: float | None = None
) -> bytes
async

Return the next stderr chunk. Only pipe mode (pty=False) carries stderr separately; in PTY mode this stream is empty and returns b"" once the process exits. Same timeout/error semantics as read().

nemo_gym.sandbox.providers.base.SandboxPtySession.resize(
rows: int,
cols: int
) -> None
async

Resize the terminal.

nemo_gym.sandbox.providers.base.SandboxPtySession.send_signal(
signal: str
) -> None
async

Deliver a named signal, e.g. "SIGTERM", to the session’s process group. Interactive shells run foreground jobs in their own group, so signals reliably reach the process only for command sessions; whether SIGINT interrupts at all also depends on the sandbox runtime’s inherited signal dispositions.

nemo_gym.sandbox.providers.base.SandboxPtySession.wait_exit(
timeout_s: float | None = None
) -> int
async

Block until the process exits and return its exit code.

nemo_gym.sandbox.providers.base.SandboxPtySession.write(
data: bytes
) -> None
async

Send raw bytes to the terminal’s stdin.

class nemo_gym.sandbox.providers.base.SandboxPtySpec(
command: str | None = None,
cwd: str | None = None,
env: dict[str, str] | None = None,
rows: int = 24,
cols: int = 80,
user: str | int | None = None,
pty: bool = True
)
Dataclass

Interactive PTY session request.

command runs under the backend’s interactive shell; None spawns the shell itself. Backends without native env/user support may rewrite the command (mirroring exec()’s user rewrite) and must raise ValueError for values they cannot honor. pty=False selects pipe mode: no TTY, stdout and stderr delivered as separate streams, rows/cols ignored. Backends that cannot size a terminal at spawn apply rows/cols as soon as it connects, so a command reading the size immediately may observe the backend default.

cols
int = 80
command
str | None = None
cwd
str | None = None
env
dict[str, str] | None = None
pty
bool = True
rows
int = 24
user
str | int | None = None
class nemo_gym.sandbox.providers.base.SandboxResources(
cpu: float | None = None,
memory_mib: int | None = None,
disk_gib: int | None = None,
gpu: int | None = None,
gpu_type: str | None = None
)
Dataclass

Provider-neutral resource request.

cpu
float | None = None
disk_gib
int | None = None
gpu
int | None = None
gpu_type
str | None = None
memory_mib
int | None = None
nemo_gym.sandbox.providers.base.SandboxResources.from_mapping(
resources: collections.abc.Mapping[str, typing.Any] | None
) -> nemo_gym.sandbox.providers.base.SandboxResources
classmethod
class nemo_gym.sandbox.providers.base.SandboxSpec(
image: str | None = None,
ttl_s: int | float | None = None,
ready_timeout_s: int | float | None = None,
workdir: str | None = None,
env: dict[str, str] = dict(),
files: dict[str, str] = dict(),
metadata: dict[str, str] = dict(),
resources: nemo_gym.sandbox.providers.base.SandboxResources | collections.abc.Mapping[str, typing.Any] = SandboxResources(),
entrypoint: list[str] | None = None,
provider_options: dict[str, typing.Any] = dict(),
ports: tuple[int, ...] | list[int] = tuple()
)
Dataclass

Sandbox creation request.

entrypoint
list[str] | None = None
env
dict[str, str] = field(default_factory=dict)
files
dict[str, str] = field(default_factory=dict)
image
str | None = None
metadata
dict[str, str] = field(default_factory=dict)
ports
tuple[int, ...] | list[int] = field(default_factory=tuple)
provider_options
dict[str, Any] = field(default_factory=dict)
ready_timeout_s
int | float | None = None
resources
SandboxResources | Mapping[str, Any] = field(default_factory=SandboxResources)
ttl_s
int | float | None = None
workdir
str | None = None
nemo_gym.sandbox.providers.base.SandboxSpec.__post_init__() -> None
class nemo_gym.sandbox.providers.base.SandboxStatus

Bases: enum.Enum

Provider-neutral sandbox lifecycle status.

ERROR
= 'error'
RUNNING
= 'running'
STARTING
= 'starting'
STOPPED
= 'stopped'
UNKNOWN
= 'unknown'
class nemo_gym.sandbox.providers.base.SupportsSandboxEndpoint()
Protocol

Optional provider capability for resolving declared service ports.

nemo_gym.sandbox.providers.base.SupportsSandboxEndpoint.endpoint(
handle: nemo_gym.sandbox.providers.base.SandboxHandle,
port: int
) -> nemo_gym.sandbox.providers.base.SandboxEndpoint
async

Resolve a declared service port to a caller-reachable endpoint.

class nemo_gym.sandbox.providers.base.SupportsSandboxPty()
Protocol

Optional provider capability: interactive PTY sessions.

async

Open an interactive terminal inside a sandbox.

class nemo_gym.sandbox.providers.base.SupportsSandboxPtyAttach()
Protocol

Optional provider capability: re-attach to a PTY session by id.

Separate from SupportsSandboxPty because it requires sessions that live in the sandbox rather than in the client, so a provider may offer terminals without offering re-attach.

nemo_gym.sandbox.providers.base.SupportsSandboxPtyAttach.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 session by id.

takeover evicts the current holder, whose session then fails with SandboxPtyError; without it, attaching to a held session fails. since is a byte offset into the session’s retained output to replay before live output (0 replays everything still retained).

nemo_gym.sandbox.providers.base.ExecResult = SandboxExecResult