> This page is for version 0.3.0.
> For other versions, use one of these documentation indexes:
> - Main (default): https://docs.nvidia.com/nemo/gym/main/llms.txt
> - 0.7.0: https://docs.nvidia.com/nemo/gym/v0.7.0/llms.txt
> - 0.6.0: https://docs.nvidia.com/nemo/gym/v0.6.0/llms.txt
> - 0.5.1: https://docs.nvidia.com/nemo/gym/v0.5.1/llms.txt
> - 0.5.0: https://docs.nvidia.com/nemo/gym/v0.5.0/llms.txt
> - 0.4.0: https://docs.nvidia.com/nemo/gym/v0.4.0/llms.txt
> - 0.3.0: https://docs.nvidia.com/nemo/gym/v0.3.0/llms.txt
> - 0.2.1: https://docs.nvidia.com/nemo/gym/v0.2.1/llms.txt

> 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.compose_fields

What a Compose service may say, and the shape each field takes before the adapter reads it.

The field allow-list of the sandbox Compose adapter and its message per offending key, the
normalisation of deploy resources, devices and gpus, restart, pull_policy, platform, extra_hosts,
hooks, networks and the provider service options, and check_compose_fields, which runs them all
over a document and is a fixed point of its own output. The two Compose scalar and environment
shape helpers, the memory size parser and the interpolation error class live here because the
field checks, the resolver and the interpolation code in nemo_gym.tasks.harbor.compose_variables
all read them, and this module sits below both. Nothing here reads a task or a record.

## Module Contents

### Classes

| Name                                                                                    | Description                                                                   |
| --------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------- |
| [`ComposeSubstitutionError`](#nemo_gym-sandbox-compose_fields-ComposeSubstitutionError) | A Compose file names a variable or an `env_file` that prepare cannot resolve. |

### Functions

| Name                                                                                        | Description                                                                                             |
| ------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------- |
| [`_bytes`](#nemo_gym-sandbox-compose_fields-_bytes)                                         | -                                                                                                       |
| [`_compose_scalar`](#nemo_gym-sandbox-compose_fields-_compose_scalar)                       | An environment value as Compose would emit it: booleans lower-case, `None` empty.                       |
| [`_environment_mapping`](#nemo_gym-sandbox-compose_fields-_environment_mapping)             | A service's `environment` as a mapping. A bare `NAME` in the list form, or a null value in the mapping  |
| [`unsupported_compose_fields`](#nemo_gym-sandbox-compose_fields-unsupported_compose_fields) | The refusals the sandbox Compose adapter raises for the keys of `document`: one message per offender in |

### Data

[`SUPPORTED_COMPOSE_FIELDS`](#nemo_gym-sandbox-compose_fields-SUPPORTED_COMPOSE_FIELDS)

[`SUPPORTED_SERVICE_FIELDS`](#nemo_gym-sandbox-compose_fields-SUPPORTED_SERVICE_FIELDS)

### API

```python
class nemo_gym.sandbox.compose_fields.ComposeSubstitutionError(
    name: str,
    message: str | None = None
)
```

**Bases:** `ValueError`

A Compose file names a variable or an `env_file` that prepare cannot resolve.

```python
nemo_gym.sandbox.compose_fields._bytes(
    value: str | int
) -> int
```

```python
nemo_gym.sandbox.compose_fields._compose_scalar(
    value: typing.Any
) -> str
```

An environment value as Compose would emit it: booleans lower-case, `None` empty.

```python
nemo_gym.sandbox.compose_fields._environment_mapping(
    service_name: str,
    environment: typing.Any,
    variables: dict[str, str]
) -> dict[str, str | None]
```

A service's `environment` as a mapping. A bare `NAME` in the list form, or a null value in the mapping
form, stands for the task variable of that name and is `None` when there is none: Compose then leaves the
variable unset in the container, even where an `env_file` sets it. `NAME=` and `NAME: ''` are empty.

```python
nemo_gym.sandbox.compose_fields.unsupported_compose_fields(
    document: typing.Any
) -> list[str]
```

The refusals the sandbox Compose adapter raises for the keys of `document`: one message per offender in
document order (the top level first, then each service), empty when every key is one the adapter starts.

Pure, so prepare runs it on a task's resolved document and reports a refused field (`deploy`,
`extra_hosts`, `platform`, a sidecar `build:`) per task before any sandbox starts, and the adapter
raises the first message at start. Only mappings are inspected: a document or service that is not one
fails the adapter's shape checks instead.

```python
nemo_gym.sandbox.compose_fields.SUPPORTED_COMPOSE_FIELDS = frozenset({'name', 'services', 'networks', 'volumes'})
```

```python
nemo_gym.sandbox.compose_fields.SUPPORTED_SERVICE_FIELDS = frozenset({'image', 'entrypoint', 'command', 'environment', 'working_dir', 'user...
```