> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.nvidia.com/nemo/gym/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.ecs_fargate.engine

ECS Fargate sandbox engine.

Runs each sandbox as an ECS Fargate task behind an SSH sidecar. Defines the host-protocol
types (`ExecResult`, `OutsideEndpoint`, `SandboxSpec`) and the engine; the Gym-facing
provider adapter lives in `provider.py`.

## Module Contents

### Classes

| Name                                                                                                | Description                                                        |
| --------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------ |
| [`EcsFargateConfig`](#nemo_gym-sandbox-providers-ecs_fargate-engine-EcsFargateConfig)               | Configuration for the ECS Fargate sandbox.                         |
| [`EcsFargateSandbox`](#nemo_gym-sandbox-providers-ecs_fargate-engine-EcsFargateSandbox)             | ECS Fargate sandbox — async :class:`Sandbox` protocol.             |
| [`ExecClient`](#nemo_gym-sandbox-providers-ecs_fargate-engine-ExecClient)                           | Async HTTP client for the exec server (through the SSH tunnel).    |
| [`ExecResult`](#nemo_gym-sandbox-providers-ecs_fargate-engine-ExecResult)                           | Result of executing a command inside a sandbox.                    |
| [`ImageBuilder`](#nemo_gym-sandbox-providers-ecs_fargate-engine-ImageBuilder)                       | Build Docker images via CodeBuild → ECR with content-hash caching. |
| [`OutsideEndpoint`](#nemo_gym-sandbox-providers-ecs_fargate-engine-OutsideEndpoint)                 | A host-side URL that must be reachable from inside the sandbox.    |
| [`SandboxSpec`](#nemo_gym-sandbox-providers-ecs_fargate-engine-SandboxSpec)                         | Per-problem sandbox requirements.                                  |
| [`SshSidecarConfig`](#nemo_gym-sandbox-providers-ecs_fargate-engine-SshSidecarConfig)               | SSH sidecar container configuration.                               |
| [`SshTunnel`](#nemo_gym-sandbox-providers-ecs_fargate-engine-SshTunnel)                             | Manages an `ssh -N` subprocess with `-L` / `-R` tunnels.           |
| [`VolumeMount`](#nemo_gym-sandbox-providers-ecs_fargate-engine-VolumeMount)                         | EFS mount (ECS Fargate). Host bind mounts are unused on Fargate.   |
| [`_OutsideEndpointRoute`](#nemo_gym-sandbox-providers-ecs_fargate-engine-_OutsideEndpointRoute)     | -                                                                  |
| [`_OutsideEndpointRouting`](#nemo_gym-sandbox-providers-ecs_fargate-engine-_OutsideEndpointRouting) | -                                                                  |

### Functions

| Name                                                                                                          | Description                                                                                   |
| ------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------- |
| [`_compute_task_def_hash`](#nemo_gym-sandbox-providers-ecs_fargate-engine-_compute_task_def_hash)             | -                                                                                             |
| [`_delete_s3_object`](#nemo_gym-sandbox-providers-ecs_fargate-engine-_delete_s3_object)                       | Best-effort delete of a transient S3 staging artifact; never raises.                          |
| [`_emergency_cleanup`](#nemo_gym-sandbox-providers-ecs_fargate-engine-_emergency_cleanup)                     | -                                                                                             |
| [`_ephemeral_storage_block`](#nemo_gym-sandbox-providers-ecs_fargate-engine-_ephemeral_storage_block)         | Task-def `ephemeralStorage` block, or `None` for Fargate's implicit 20 GiB default.           |
| [`_free_port`](#nemo_gym-sandbox-providers-ecs_fargate-engine-_free_port)                                     | -                                                                                             |
| [`_is_ecr_image_ref`](#nemo_gym-sandbox-providers-ecs_fargate-engine-_is_ecr_image_ref)                       | True for references already pointing at an ECR registry host.                                 |
| [`_is_retryable_error`](#nemo_gym-sandbox-providers-ecs_fargate-engine-_is_retryable_error)                   | -                                                                                             |
| [`_port_from_url`](#nemo_gym-sandbox-providers-ecs_fargate-engine-_port_from_url)                             | -                                                                                             |
| [`_require_aws_sdks`](#nemo_gym-sandbox-providers-ecs_fargate-engine-_require_aws_sdks)                       | -                                                                                             |
| [`_retry_with_backoff`](#nemo_gym-sandbox-providers-ecs_fargate-engine-_retry_with_backoff)                   | -                                                                                             |
| [`_sanitize_id`](#nemo_gym-sandbox-providers-ecs_fargate-engine-_sanitize_id)                                 | -                                                                                             |
| [`_validate_fargate_cpu_memory`](#nemo_gym-sandbox-providers-ecs_fargate-engine-_validate_fargate_cpu_memory) | Validate a Fargate cpu (units) + memory (MiB) pair; Fargate rejects unsupported combinations. |
| [`_validate_image_ref`](#nemo_gym-sandbox-providers-ecs_fargate-engine-_validate_image_ref)                   | Reject an image reference with characters outside the safe set (shell-injection guard).       |
| [`build_ssh_sidecar_container`](#nemo_gym-sandbox-providers-ecs_fargate-engine-build_ssh_sidecar_container)   | -                                                                                             |
| [`download_secret_to_file`](#nemo_gym-sandbox-providers-ecs_fargate-engine-download_secret_to_file)           | Fetch a Secrets Manager secret → temp file (mode 0600).                                       |
| [`download_secret_to_string`](#nemo_gym-sandbox-providers-ecs_fargate-engine-download_secret_to_string)       | -                                                                                             |
| [`resolve_ecs_config_from_ssm`](#nemo_gym-sandbox-providers-ecs_fargate-engine-resolve_ecs_config_from_ssm)   | Read ECS sandbox config from SSM Parameter Store.                                             |

### Data

[`DEFAULT_EXEC_SERVER_PORT`](#nemo_gym-sandbox-providers-ecs_fargate-engine-DEFAULT_EXEC_SERVER_PORT)

[`DEFAULT_SSHD_PORT`](#nemo_gym-sandbox-providers-ecs_fargate-engine-DEFAULT_SSHD_PORT)

[`DEFAULT_SSM_PROJECT`](#nemo_gym-sandbox-providers-ecs_fargate-engine-DEFAULT_SSM_PROJECT)

[`EXEC_SERVER_SCRIPT`](#nemo_gym-sandbox-providers-ecs_fargate-engine-EXEC_SERVER_SCRIPT)

[`T`](#nemo_gym-sandbox-providers-ecs_fargate-engine-T)

[`_ECR_IMAGE_REF_RE`](#nemo_gym-sandbox-providers-ecs_fargate-engine-_ECR_IMAGE_REF_RE)

[`_EXEC_SERVER_B64`](#nemo_gym-sandbox-providers-ecs_fargate-engine-_EXEC_SERVER_B64)

[`_FARGATE_MEMORY_RANGE_MIB`](#nemo_gym-sandbox-providers-ecs_fargate-engine-_FARGATE_MEMORY_RANGE_MIB)

[`_IMAGE_REF_RE`](#nemo_gym-sandbox-providers-ecs_fargate-engine-_IMAGE_REF_RE)

[`_PER_INVOCATION_ENV_KEYS`](#nemo_gym-sandbox-providers-ecs_fargate-engine-_PER_INVOCATION_ENV_KEYS)

[`_PROCESS_NONCE`](#nemo_gym-sandbox-providers-ecs_fargate-engine-_PROCESS_NONCE)

[`_RETRYABLE_CODES`](#nemo_gym-sandbox-providers-ecs_fargate-engine-_RETRYABLE_CODES)

[`_RETRYABLE_MESSAGES`](#nemo_gym-sandbox-providers-ecs_fargate-engine-_RETRYABLE_MESSAGES)

[`_TRANSIENT_ERRORS`](#nemo_gym-sandbox-providers-ecs_fargate-engine-_TRANSIENT_ERRORS)

[`_active_sandboxes`](#nemo_gym-sandbox-providers-ecs_fargate-engine-_active_sandboxes)

[`_atexit_registered`](#nemo_gym-sandbox-providers-ecs_fargate-engine-_atexit_registered)

[`_cleanup_lock`](#nemo_gym-sandbox-providers-ecs_fargate-engine-_cleanup_lock)

[`_exec_server_url_cache`](#nemo_gym-sandbox-providers-ecs_fargate-engine-_exec_server_url_cache)

[`_s3_delete_warned`](#nemo_gym-sandbox-providers-ecs_fargate-engine-_s3_delete_warned)

[`_ssm_config_cache`](#nemo_gym-sandbox-providers-ecs_fargate-engine-_ssm_config_cache)

[`_task_def_cache`](#nemo_gym-sandbox-providers-ecs_fargate-engine-_task_def_cache)

[`_task_def_cache_lock`](#nemo_gym-sandbox-providers-ecs_fargate-engine-_task_def_cache_lock)

[`_task_def_inflight`](#nemo_gym-sandbox-providers-ecs_fargate-engine-_task_def_inflight)

[`logger`](#nemo_gym-sandbox-providers-ecs_fargate-engine-logger)

### API

```python
class nemo_gym.sandbox.providers.ecs_fargate.engine.EcsFargateConfig(
    region: str | None = None,
    cluster: str = '',
    subnets: list[str] = list(),
    security_groups: list[str] = list(),
    assign_public_ip: bool = False,
    task_definition: str | None = None,
    task_definition_family_prefix: str = 'ecs-sandbox',
    image_template: str | None = None,
    container_name: str = 'main',
    container_port: int | None = None,
    cpu: str = '4096',
    memory: str = '8192',
    ephemeral_storage_gib: int | None = None,
    platform_version: str | None = None,
    execution_role_arn: str | None = None,
    task_role_arn: str | None = None,
    extra_env: dict[str, str] | None = None,
    log_group: str | None = None,
    log_stream_prefix: str | None = None,
    max_task_lifetime_sec: int = 14400,
    startup_timeout_sec: float = 300.0,
    poll_interval_sec: float = 2.0,
    run_task_max_retries: int = 30,
    ssh_sidecar: nemo_gym.sandbox.providers.ecs_fargate.engine.SshSidecarConfig | None = None,
    s3_bucket: str | None = None,
    s3_prefix: str | None = None,
    ecr_repository: str | None = None,
    environment_dir: str | None = None,
    codebuild_project: str | None = None,
    codebuild_service_role: str | None = None,
    codebuild_compute_type: str = 'BUILD_GENERAL1_MEDIUM',
    codebuild_build_timeout: int = 60,
    dockerhub_secret_arn: str | None = None,
    build_parallelism: int = 50,
    auto_mirror: bool = True,
    efs_filesystem_id: str | None = None,
    efs_access_point_id: str | None = None,
    ssm_project: str = DEFAULT_SSM_PROJECT
)
```

Dataclass

Configuration for the ECS Fargate sandbox.

```python
class nemo_gym.sandbox.providers.ecs_fargate.engine.EcsFargateSandbox(
    spec: nemo_gym.sandbox.providers.ecs_fargate.engine.SandboxSpec,
    ecs_config: nemo_gym.sandbox.providers.ecs_fargate.engine.EcsFargateConfig
)
```

ECS Fargate sandbox — async :class:`Sandbox` protocol.

```python
nemo_gym.sandbox.providers.ecs_fargate.engine.EcsFargateSandbox.__aenter__() -> typing.Self
```

async

```python
nemo_gym.sandbox.providers.ecs_fargate.engine.EcsFargateSandbox.__aexit__(
    exc: object = ()
) -> None
```

async

```python
nemo_gym.sandbox.providers.ecs_fargate.engine.EcsFargateSandbox._build_container_command(
    sidecar: nemo_gym.sandbox.providers.ecs_fargate.engine.SshSidecarConfig
) -> list[str] | None
```

```python
nemo_gym.sandbox.providers.ecs_fargate.engine.EcsFargateSandbox._build_efs_volumes() -> tuple[list[dict[str, typing.Any]], list[dict[str, typing.Any]]]
```

Build EFS volume defs + mount points from spec.volumes.

A volume may name its own filesystem/access point or inherit the provider-level
`efs_filesystem_id` / `efs_access_point_id` defaults.

```python
nemo_gym.sandbox.providers.ecs_fargate.engine.EcsFargateSandbox._build_env_vars() -> dict[str, str]
```

```python
nemo_gym.sandbox.providers.ecs_fargate.engine.EcsFargateSandbox._cleanup() -> None
```

```python
nemo_gym.sandbox.providers.ecs_fargate.engine.EcsFargateSandbox._do_register(
    payload: dict[str, typing.Any]
) -> str
```

```python
nemo_gym.sandbox.providers.ecs_fargate.engine.EcsFargateSandbox._do_start() -> None
```

```python
nemo_gym.sandbox.providers.ecs_fargate.engine.EcsFargateSandbox._get_task_public_ip() -> str
```

```python
nemo_gym.sandbox.providers.ecs_fargate.engine.EcsFargateSandbox._init_aws_clients() -> None
```

```python
nemo_gym.sandbox.providers.ecs_fargate.engine.EcsFargateSandbox._make_family_name() -> str
```

```python
nemo_gym.sandbox.providers.ecs_fargate.engine.EcsFargateSandbox._open_tunnel(
    sidecar: nemo_gym.sandbox.providers.ecs_fargate.engine.SshSidecarConfig
) -> None
```

```python
nemo_gym.sandbox.providers.ecs_fargate.engine.EcsFargateSandbox._register_for_cleanup() -> None
```

```python
nemo_gym.sandbox.providers.ecs_fargate.engine.EcsFargateSandbox._register_from_base(
    base: dict,
    image: str,
    command: list[str] | None,
    env: dict[str, str],
    sidecar_def: dict,
    log_cfg: dict | None
) -> str
```

```python
nemo_gym.sandbox.providers.ecs_fargate.engine.EcsFargateSandbox._register_from_scratch(
    image: str,
    command: list[str] | None,
    env: dict[str, str],
    sidecar_def: dict,
    log_cfg: dict | None
) -> str
```

```python
nemo_gym.sandbox.providers.ecs_fargate.engine.EcsFargateSandbox._register_task_def_fresh(
    payload: dict[str, typing.Any],
    h: str
) -> str
```

```python
nemo_gym.sandbox.providers.ecs_fargate.engine.EcsFargateSandbox._register_task_definition(
    image: str,
    command: list[str] | None,
    env: dict[str, str],
    sidecar_def: dict[str, typing.Any]
) -> str
```

```python
nemo_gym.sandbox.providers.ecs_fargate.engine.EcsFargateSandbox._release_inflight(
    h: str,
    event: threading.Event
) -> None
```

```python
nemo_gym.sandbox.providers.ecs_fargate.engine.EcsFargateSandbox._render_env_value(
    value: str
) -> str
```

```python
nemo_gym.sandbox.providers.ecs_fargate.engine.EcsFargateSandbox._require_exec_client() -> None
```

```python
nemo_gym.sandbox.providers.ecs_fargate.engine.EcsFargateSandbox._resolve_image(
    built_image: str | None = None
) -> str
```

```python
nemo_gym.sandbox.providers.ecs_fargate.engine.EcsFargateSandbox._run_task(
    task_def_arn: str
) -> str
```

```python
nemo_gym.sandbox.providers.ecs_fargate.engine.EcsFargateSandbox._split_env(
    env: dict[str, str]
) -> tuple[dict[str, str], dict[str, str]]
```

```python
nemo_gym.sandbox.providers.ecs_fargate.engine.EcsFargateSandbox._ssm_lookup_task_def(
    h: str
) -> str | None
```

```python
nemo_gym.sandbox.providers.ecs_fargate.engine.EcsFargateSandbox._ssm_write_task_def(
    h: str,
    arn: str
) -> None
```

```python
nemo_gym.sandbox.providers.ecs_fargate.engine.EcsFargateSandbox._sync_stop() -> None
```

Synchronous stop for emergency cleanup (atexit handler).

```python
nemo_gym.sandbox.providers.ecs_fargate.engine.EcsFargateSandbox._unregister_from_cleanup() -> None
```

```python
nemo_gym.sandbox.providers.ecs_fargate.engine.EcsFargateSandbox._upload_exec_server() -> str
```

```python
nemo_gym.sandbox.providers.ecs_fargate.engine.EcsFargateSandbox._upload_via_s3(
    paths: list[pathlib.Path],
    dest_dir: str,
    arcnames: dict[pathlib.Path, str] | None = None
) -> None
```

async

```python
nemo_gym.sandbox.providers.ecs_fargate.engine.EcsFargateSandbox._wait_for_running() -> None
```

```python
nemo_gym.sandbox.providers.ecs_fargate.engine.EcsFargateSandbox._wait_for_ssh_ready(
    host: str,
    port: int,
    timeout: float
) -> None
```

staticmethod

```python
nemo_gym.sandbox.providers.ecs_fargate.engine.EcsFargateSandbox.download(
    remote_path: str,
    local_path: pathlib.Path
) -> None
```

async

```python
nemo_gym.sandbox.providers.ecs_fargate.engine.EcsFargateSandbox.exec(
    command: str,
    timeout_sec: float = 180,
    cwd: str | None = None,
    env: dict[str, str] | None = None,
    user: str | int | None = None
) -> nemo_gym.sandbox.providers.ecs_fargate.engine.ExecResult
```

async

```python
nemo_gym.sandbox.providers.ecs_fargate.engine.EcsFargateSandbox.reconnect_tunnel() -> None
```

async

```python
nemo_gym.sandbox.providers.ecs_fargate.engine.EcsFargateSandbox.resolve_outside_endpoint(
    url: str
) -> str
```

```python
nemo_gym.sandbox.providers.ecs_fargate.engine.EcsFargateSandbox.resolved_endpoint_url(
    env_var: str
) -> str | None
```

```python
nemo_gym.sandbox.providers.ecs_fargate.engine.EcsFargateSandbox.start(
    outside_endpoints: list[nemo_gym.sandbox.providers.ecs_fargate.engine.OutsideEndpoint] | None = None
) -> None
```

async

```python
nemo_gym.sandbox.providers.ecs_fargate.engine.EcsFargateSandbox.stop() -> None
```

async

```python
nemo_gym.sandbox.providers.ecs_fargate.engine.EcsFargateSandbox.upload(
    local_path: pathlib.Path,
    remote_path: str
) -> None
```

async

```python
class nemo_gym.sandbox.providers.ecs_fargate.engine.ExecClient(
    port: int,
    connect_timeout: float = 30.0
)
```

Async HTTP client for the exec server (through the SSH tunnel).

Methods are coroutines so concurrent requests occupy event-loop slots rather than executor
threads, scaling past asyncio's default thread-pool cap.

```python
nemo_gym.sandbox.providers.ecs_fargate.engine.ExecClient._ensure_session() -> aiohttp.ClientSession
```

async

```python
nemo_gym.sandbox.providers.ecs_fargate.engine.ExecClient._post(
    path: str,
    body: dict[str, typing.Any],
    timeout_override: float | None = None,
    max_retries: int = 4
) -> dict[str, typing.Any]
```

async

```python
nemo_gym.sandbox.providers.ecs_fargate.engine.ExecClient._request(
    label: str,
    url: str,
    method: str,
    data: bytes | None = None,
    headers: dict[str, str] | None = None,
    timeout: float,
    max_retries: int
) -> bytes
```

async

```python
nemo_gym.sandbox.providers.ecs_fargate.engine.ExecClient.close() -> None
```

async

```python
nemo_gym.sandbox.providers.ecs_fargate.engine.ExecClient.download(
    remote_path: str,
    max_retries: int = 3
) -> bytes
```

async

```python
nemo_gym.sandbox.providers.ecs_fargate.engine.ExecClient.exec(
    cmd: str,
    timeout: int = 300
) -> nemo_gym.sandbox.providers.ecs_fargate.engine.ExecResult
```

async

```python
nemo_gym.sandbox.providers.ecs_fargate.engine.ExecClient.health() -> bool
```

async

```python
nemo_gym.sandbox.providers.ecs_fargate.engine.ExecClient.upload(
    remote_path: str,
    data: bytes | pathlib.Path,
    mode: str | None = None,
    max_retries: int = 3
) -> None
```

async

```python
class nemo_gym.sandbox.providers.ecs_fargate.engine.ExecResult(
    stdout: str,
    stderr: str,
    return_code: int
)
```

Dataclass

Result of executing a command inside a sandbox.

```python
class nemo_gym.sandbox.providers.ecs_fargate.engine.ImageBuilder()
```

Build Docker images via CodeBuild → ECR with content-hash caching.

```python
nemo_gym.sandbox.providers.ecs_fargate.engine.ImageBuilder._build_and_push(
    cfg: nemo_gym.sandbox.providers.ecs_fargate.engine.EcsFargateConfig,
    environment_name: str,
    tag: str,
    image_url: str
) -> None
```

classmethod

```python
nemo_gym.sandbox.providers.ecs_fargate.engine.ImageBuilder._ecr_region(
    ecr_repository: str,
    fallback: str | None = None
) -> str | None
```

staticmethod

Extract the region from an ECR repo URL like '123.dkr.ecr.us-west-2.amazonaws.com/repo'.

```python
nemo_gym.sandbox.providers.ecs_fargate.engine.ImageBuilder._generate_buildspec(
    cfg: nemo_gym.sandbox.providers.ecs_fargate.engine.EcsFargateConfig,
    repo_name: str,
    tag: str,
    image_url: str
) -> str
```

staticmethod

```python
nemo_gym.sandbox.providers.ecs_fargate.engine.ImageBuilder._generate_mirror_buildspec(
    cfg: nemo_gym.sandbox.providers.ecs_fargate.engine.EcsFargateConfig,
    src_image: str,
    ecr_url: str
) -> str
```

staticmethod

```python
nemo_gym.sandbox.providers.ecs_fargate.engine.ImageBuilder._poll_codebuild(
    cb: typing.Any,
    build_id: str,
    image_url: str
) -> None
```

staticmethod

```python
nemo_gym.sandbox.providers.ecs_fargate.engine.ImageBuilder._resolve_codebuild_project(
    cfg: nemo_gym.sandbox.providers.ecs_fargate.engine.EcsFargateConfig,
    cb: typing.Any
) -> str
```

staticmethod

```python
nemo_gym.sandbox.providers.ecs_fargate.engine.ImageBuilder._run_deduped_build(
    cfg: nemo_gym.sandbox.providers.ecs_fargate.engine.EcsFargateConfig,
    tag: str,
    image_url: str,
    force: bool,
    build: typing.Callable[[], None]
) -> str
```

classmethod

Run `build` for `tag` at most once across threads, returning the ECR `image_url`.

Concurrent callers wait on a shared in-flight event outside `cls._lock` (so one waiter
can't stall other tags' builds), then confirm via ECR -- a failed build also sets the event.

```python
nemo_gym.sandbox.providers.ecs_fargate.engine.ImageBuilder._upload_build_context(
    cfg: nemo_gym.sandbox.providers.ecs_fargate.engine.EcsFargateConfig,
    environment_name: str,
    nonce: str
) -> str
```

staticmethod

```python
nemo_gym.sandbox.providers.ecs_fargate.engine.ImageBuilder.docker_push_to_ecr(
    local_image: str,
    ecr_repository: str,
    tag: str
) -> str
```

staticmethod

Tag a local Docker image and push it to ECR. Returns the ECR URL.

```python
nemo_gym.sandbox.providers.ecs_fargate.engine.ImageBuilder.ecr_docker_login(
    ecr_repository: str,
    region: str | None = None
) -> None
```

staticmethod

Authenticate the local Docker daemon against an ECR registry.

```python
nemo_gym.sandbox.providers.ecs_fargate.engine.ImageBuilder.ensure_image_built(
    cfg: nemo_gym.sandbox.providers.ecs_fargate.engine.EcsFargateConfig,
    environment_name: str,
    force_build: bool = False
) -> str
```

classmethod

```python
nemo_gym.sandbox.providers.ecs_fargate.engine.ImageBuilder.ensure_mirrored(
    cfg: nemo_gym.sandbox.providers.ecs_fargate.engine.EcsFargateConfig,
    src_image: str,
    force: bool = False
) -> str
```

classmethod

Ensure `src_image` is present in the ECR mirror tag, mirroring it on demand if not.

Mirrors via a self-contained CodeBuild job (privileged DinD: login, pull, retag, push).
Concurrent callers dedup on a shared in-flight event, like :meth:`ensure_image_built`.

```python
nemo_gym.sandbox.providers.ecs_fargate.engine.ImageBuilder.get_ecr_image_tag(
    environment_dir: str | pathlib.Path,
    environment_name: str
) -> str
```

staticmethod

```python
nemo_gym.sandbox.providers.ecs_fargate.engine.ImageBuilder.image_exists_in_ecr(
    ecr_repository: str,
    tag: str,
    region: str | None = None
) -> bool
```

staticmethod

```python
nemo_gym.sandbox.providers.ecs_fargate.engine.ImageBuilder.list_ecr_tags(
    ecr_repository: str,
    region: str | None = None
) -> set[str]
```

staticmethod

Return all image tags present in an ECR repository (paginated `list_images`).

```python
nemo_gym.sandbox.providers.ecs_fargate.engine.ImageBuilder.run_buildspec_via_codebuild(
    cfg: nemo_gym.sandbox.providers.ecs_fargate.engine.EcsFargateConfig,
    buildspec: str,
    job_label: str = 'harness-build',
    timeout_minutes: int | None = None
) -> None
```

classmethod

Run a self-contained buildspec via CodeBuild (privileged DinD, `NO_SOURCE`).

```python
class nemo_gym.sandbox.providers.ecs_fargate.engine.OutsideEndpoint(
    url: str,
    env_var: str
)
```

Dataclass

A host-side URL that must be reachable from inside the sandbox.

The sandbox rewrites *url* for its network topology and exposes the
resolved address as the environment variable *env\_var* inside the
container.

```python
class nemo_gym.sandbox.providers.ecs_fargate.engine.SandboxSpec(
    image: str,
    workdir: str = '/workspace',
    env: dict[str, str] = dict(),
    files: dict[str, str] = dict(),
    entrypoint: str | None = None,
    volumes: list[nemo_gym.sandbox.providers.ecs_fargate.engine.VolumeMount] = list(),
    environment_dir: str | None = None
)
```

Dataclass

Per-problem sandbox requirements.

```python
class nemo_gym.sandbox.providers.ecs_fargate.engine.SshSidecarConfig(
    sshd_port: int = 2222,
    ssh_ready_timeout_sec: float = 300.0,
    public_key_secret_arn: str = '',
    private_key_secret_arn: str = '',
    image: str | None = None,
    exec_server_port: int | None = None
)
```

Dataclass

SSH sidecar container configuration.

exec\_server\_port set → exec-server mode (one-way tunnel).
exec\_server\_port None → agent-server mode (two-way tunnel).

```python
class nemo_gym.sandbox.providers.ecs_fargate.engine.SshTunnel(
    host: str,
    port: int = 2222,
    user: str = 'root',
    key_file: str,
    forward_port: int | None = None,
    forwards: list[str] | None = None,
    reverses: list[str] | None = None,
    local_port_override: int | None = None
)
```

Manages an `ssh -N` subprocess with `-L` / `-R` tunnels.

```python
nemo_gym.sandbox.providers.ecs_fargate.engine.SshTunnel.__enter__() -> nemo_gym.sandbox.providers.ecs_fargate.engine.SshTunnel
```

```python
nemo_gym.sandbox.providers.ecs_fargate.engine.SshTunnel.__exit__(
    exc: object = ()
) -> None
```

```python
nemo_gym.sandbox.providers.ecs_fargate.engine.SshTunnel._build_ssh_cmd() -> list[str]
```

```python
nemo_gym.sandbox.providers.ecs_fargate.engine.SshTunnel._kill() -> None
```

```python
nemo_gym.sandbox.providers.ecs_fargate.engine.SshTunnel._poll_health(
    url: str,
    timeout: float
) -> None
```

```python
nemo_gym.sandbox.providers.ecs_fargate.engine.SshTunnel._wait_for_local_port(
    port: int,
    timeout: float = 30.0
) -> None
```

```python
nemo_gym.sandbox.providers.ecs_fargate.engine.SshTunnel.check_health() -> bool
```

```python
nemo_gym.sandbox.providers.ecs_fargate.engine.SshTunnel.close() -> None
```

```python
nemo_gym.sandbox.providers.ecs_fargate.engine.SshTunnel.open(
    max_retries: int = 15,
    initial_backoff: float = 5.0
) -> None
```

```python
nemo_gym.sandbox.providers.ecs_fargate.engine.SshTunnel.wait_ready(
    health_url: str | None = None,
    timeout: float = 300.0
) -> None
```

```python
class nemo_gym.sandbox.providers.ecs_fargate.engine.VolumeMount(
    host_path: str = '',
    container_path: str = '',
    readonly: bool = False,
    efs: bool = False,
    efs_filesystem_id: str | None = None,
    efs_root_directory: str | None = None,
    efs_access_point_id: str | None = None
)
```

Dataclass

EFS mount (ECS Fargate). Host bind mounts are unused on Fargate.

```python
class nemo_gym.sandbox.providers.ecs_fargate.engine._OutsideEndpointRoute(
    endpoint: nemo_gym.sandbox.providers.ecs_fargate.engine.OutsideEndpoint,
    source_netloc: str,
    host: str,
    target_port: int,
    remote_port: int,
    scheme: str
)
```

Dataclass

```python
nemo_gym.sandbox.providers.ecs_fargate.engine._OutsideEndpointRoute._rewrite(
    parsed: urllib.parse.ParseResult
) -> str
```

```python
nemo_gym.sandbox.providers.ecs_fargate.engine._OutsideEndpointRoute.for_endpoint(
    endpoint: nemo_gym.sandbox.providers.ecs_fargate.engine.OutsideEndpoint,
    remote_port: int | None = None
) -> nemo_gym.sandbox.providers.ecs_fargate.engine._OutsideEndpointRoute
```

classmethod

```python
nemo_gym.sandbox.providers.ecs_fargate.engine._OutsideEndpointRoute.resolve_url(
    url: str
) -> str
```

```python
nemo_gym.sandbox.providers.ecs_fargate.engine._OutsideEndpointRoute.resolved_endpoint_url() -> str
```

```python
class nemo_gym.sandbox.providers.ecs_fargate.engine._OutsideEndpointRouting(
    endpoints: tuple[nemo_gym.sandbox.providers.ecs_fargate.engine.OutsideEndpoint, ...] = (),
    _routes_by_env: dict[str, nemo_gym.sandbox.providers.ecs_fargate.engine._OutsideEndpointRoute] = dict(),
    _reverse_specs: tuple[str, ...] = (),
    _agent_tunnel_port: int | None = None
)
```

Dataclass

```python
nemo_gym.sandbox.providers.ecs_fargate.engine._OutsideEndpointRouting._allocate_reverse_port(
    preferred: int,
    used_ports: set[int]
) -> int
```

staticmethod

```python
nemo_gym.sandbox.providers.ecs_fargate.engine._OutsideEndpointRouting.agent_tunnel_target() -> tuple[str, int]
```

```python
nemo_gym.sandbox.providers.ecs_fargate.engine._OutsideEndpointRouting.empty(
    endpoints: list[nemo_gym.sandbox.providers.ecs_fargate.engine.OutsideEndpoint] | None = None
) -> nemo_gym.sandbox.providers.ecs_fargate.engine._OutsideEndpointRouting
```

classmethod

```python
nemo_gym.sandbox.providers.ecs_fargate.engine._OutsideEndpointRouting.env_overrides() -> dict[str, str]
```

```python
nemo_gym.sandbox.providers.ecs_fargate.engine._OutsideEndpointRouting.for_agent_server(
    endpoints: list[nemo_gym.sandbox.providers.ecs_fargate.engine.OutsideEndpoint]
) -> nemo_gym.sandbox.providers.ecs_fargate.engine._OutsideEndpointRouting
```

classmethod

```python
nemo_gym.sandbox.providers.ecs_fargate.engine._OutsideEndpointRouting.for_exec_server(
    endpoints: list[nemo_gym.sandbox.providers.ecs_fargate.engine.OutsideEndpoint],
    sidecar: nemo_gym.sandbox.providers.ecs_fargate.engine.SshSidecarConfig
) -> nemo_gym.sandbox.providers.ecs_fargate.engine._OutsideEndpointRouting
```

classmethod

```python
nemo_gym.sandbox.providers.ecs_fargate.engine._OutsideEndpointRouting.resolve_url(
    url: str
) -> str
```

```python
nemo_gym.sandbox.providers.ecs_fargate.engine._OutsideEndpointRouting.resolved_endpoint_url(
    env_var: str
) -> str | None
```

```python
nemo_gym.sandbox.providers.ecs_fargate.engine._compute_task_def_hash(
    payload: dict[str, typing.Any]
) -> str
```

```python
nemo_gym.sandbox.providers.ecs_fargate.engine._delete_s3_object(
    cfg: nemo_gym.sandbox.providers.ecs_fargate.engine.EcsFargateConfig,
    key: str
) -> None
```

Best-effort delete of a transient S3 staging artifact; never raises.

Warns once if the role lacks `s3:DeleteObject` (objects then rely on a bucket lifecycle policy).

```python
nemo_gym.sandbox.providers.ecs_fargate.engine._emergency_cleanup() -> None
```

```python
nemo_gym.sandbox.providers.ecs_fargate.engine._ephemeral_storage_block(
    requested: typing.Any
) -> dict[str, int] | None
```

Task-def `ephemeralStorage` block, or `None` for Fargate's implicit 20 GiB default.

Fargate accepts only 21-200 GiB explicitly (20 is valid only as the omitted default).

```python
nemo_gym.sandbox.providers.ecs_fargate.engine._free_port() -> int
```

```python
nemo_gym.sandbox.providers.ecs_fargate.engine._is_ecr_image_ref(
    image: str
) -> bool
```

True for references already pointing at an ECR registry host.

Such references (e.g. an image resolved against the configured ECR mirror)
must be used as-is; reapplying the `ecr_repository` + sanitize rewrite
would corrupt the tag.

```python
nemo_gym.sandbox.providers.ecs_fargate.engine._is_retryable_error(
    exc: Exception
) -> bool
```

```python
nemo_gym.sandbox.providers.ecs_fargate.engine._port_from_url(
    parsed: urllib.parse.ParseResult
) -> int
```

```python
nemo_gym.sandbox.providers.ecs_fargate.engine._require_aws_sdks()
```

```python
nemo_gym.sandbox.providers.ecs_fargate.engine._retry_with_backoff(
    func: typing.Callable[[], nemo_gym.sandbox.providers.ecs_fargate.engine.T],
    operation_name: str,
    max_retries: int | None = None,
    base_delay: float = 1.0,
    max_delay: float = 60.0,
    jitter: float = 0.5
) -> nemo_gym.sandbox.providers.ecs_fargate.engine.T
```

```python
nemo_gym.sandbox.providers.ecs_fargate.engine._sanitize_id(
    value: str,
    max_len: int = 100
) -> str
```

```python
nemo_gym.sandbox.providers.ecs_fargate.engine._validate_fargate_cpu_memory(
    cpu: int,
    memory: int
) -> None
```

Validate a Fargate cpu (units) + memory (MiB) pair; Fargate rejects unsupported combinations.

```python
nemo_gym.sandbox.providers.ecs_fargate.engine._validate_image_ref(
    ref: str
) -> None
```

Reject an image reference with characters outside the safe set (shell-injection guard).

```python
nemo_gym.sandbox.providers.ecs_fargate.engine.build_ssh_sidecar_container(
    sidecar_cfg: nemo_gym.sandbox.providers.ecs_fargate.engine.SshSidecarConfig,
    public_key_value: str,
    max_lifetime_sec: int,
    log_group: str | None = None,
    log_region: str = 'us-east-1',
    log_stream_prefix: str = 'ecs-sandbox'
) -> dict[str, typing.Any]
```

```python
nemo_gym.sandbox.providers.ecs_fargate.engine.download_secret_to_file(
    secret_arn: str,
    region: str | None = None
) -> str
```

Fetch a Secrets Manager secret → temp file (mode 0600).

```python
nemo_gym.sandbox.providers.ecs_fargate.engine.download_secret_to_string(
    secret_arn: str,
    region: str | None = None
) -> str
```

```python
nemo_gym.sandbox.providers.ecs_fargate.engine.resolve_ecs_config_from_ssm(
    region: str,
    project: str = DEFAULT_SSM_PROJECT
) -> dict[str, typing.Any]
```

Read ECS sandbox config from SSM Parameter Store.

Returns a dict matching the JSON structure written by Terraform
(cluster, subnets, security\_groups, roles, SSH ARNs, EFS, etc.).
Results are cached per (region, project) for the process lifetime.

```python
nemo_gym.sandbox.providers.ecs_fargate.engine.DEFAULT_EXEC_SERVER_PORT = 19542
```

```python
nemo_gym.sandbox.providers.ecs_fargate.engine.DEFAULT_SSHD_PORT = 52222
```

```python
nemo_gym.sandbox.providers.ecs_fargate.engine.DEFAULT_SSM_PROJECT = 'harbor'
```

```python
nemo_gym.sandbox.providers.ecs_fargate.engine.EXEC_SERVER_SCRIPT = '#!/usr/bin/env python3\n"""Zero-dependency HTTP exec server for sandbox contain...
```

```python
nemo_gym.sandbox.providers.ecs_fargate.engine.T = TypeVar('T')
```

```python
nemo_gym.sandbox.providers.ecs_fargate.engine._ECR_IMAGE_REF_RE = re.compile('^[0-9]{12}\\.dkr\\.ecr\\.[a-z0-9-]+\\.amazonaws\\.com/', re.IGNORECA...
```

```python
nemo_gym.sandbox.providers.ecs_fargate.engine._EXEC_SERVER_B64 = base64.b64encode(EXEC_SERVER_SCRIPT.encode()).decode()
```

```python
nemo_gym.sandbox.providers.ecs_fargate.engine._FARGATE_MEMORY_RANGE_MIB: dict[int, tuple[int, int]] = {256: (512, 2048), 512: (1024, 4096), 1024: (2048, 8192), 2048: (4096, 16384), 4...
```

```python
nemo_gym.sandbox.providers.ecs_fargate.engine._IMAGE_REF_RE = re.compile('^[A-Za-z0-9][A-Za-z0-9._:/@-]*$')
```

```python
nemo_gym.sandbox.providers.ecs_fargate.engine._PER_INVOCATION_ENV_KEYS: frozenset[str] = frozenset({'_NEL_EFS_SESSION'})
```

```python
nemo_gym.sandbox.providers.ecs_fargate.engine._PROCESS_NONCE = f'{int(time.time())}-{uuid.uuid4().hex[:8]}'
```

```python
nemo_gym.sandbox.providers.ecs_fargate.engine._RETRYABLE_CODES = frozenset({'ThrottlingException', 'TooManyRequestsException', 'ServiceUnavailabl...
```

```python
nemo_gym.sandbox.providers.ecs_fargate.engine._RETRYABLE_MESSAGES = ('capacity is unavailable', 'rate exceeded', 'too many concurrent', 'throttl', '...
```

```python
nemo_gym.sandbox.providers.ecs_fargate.engine._TRANSIENT_ERRORS = (ConnectionResetError, ConnectionRefusedError, ConnectionAbortedError, BrokenPip...
```

```python
nemo_gym.sandbox.providers.ecs_fargate.engine._active_sandboxes: dict[int, Any] = {}
```

```python
nemo_gym.sandbox.providers.ecs_fargate.engine._atexit_registered = False
```

```python
nemo_gym.sandbox.providers.ecs_fargate.engine._cleanup_lock = threading.RLock()
```

```python
nemo_gym.sandbox.providers.ecs_fargate.engine._exec_server_url_cache: dict[str, str] = {}
```

```python
nemo_gym.sandbox.providers.ecs_fargate.engine._s3_delete_warned = False
```

```python
nemo_gym.sandbox.providers.ecs_fargate.engine._ssm_config_cache: dict[str, dict[str, Any]] = {}
```

```python
nemo_gym.sandbox.providers.ecs_fargate.engine._task_def_cache: dict[str, str] = {}
```

```python
nemo_gym.sandbox.providers.ecs_fargate.engine._task_def_cache_lock = threading.Lock()
```

```python
nemo_gym.sandbox.providers.ecs_fargate.engine._task_def_inflight: dict[str, Event] = {}
```

```python
nemo_gym.sandbox.providers.ecs_fargate.engine.logger = logging.getLogger(__name__)
```