> 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.cli.env

## Module Contents

### Classes

| Name                                               | Description                                                                                       |
| -------------------------------------------------- | ------------------------------------------------------------------------------------------------- |
| [`PipListConfig`](#nemo_gym-cli-env-PipListConfig) | -                                                                                                 |
| [`RunConfig`](#nemo_gym-cli-env-RunConfig)         | Start NeMo Gym servers for agents, models, and resources.                                         |
| [`RunHelper`](#nemo_gym-cli-env-RunHelper)         | -                                                                                                 |
| [`TestAllConfig`](#nemo_gym-cli-env-TestAllConfig) | Run tests for all server modules in the project.                                                  |
| [`TestConfig`](#nemo_gym-cli-env-TestConfig)       | Test a specific server module by running its pytest suite and optionally validating example data. |

### Functions

| Name                                                                                   | Description                                                                                               |
| -------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------- |
| [`_collect_model_endpoints`](#nemo_gym-cli-env-_collect_model_endpoints)               | The upstream model endpoints named in the resolved config, as (config key, url) pairs.                    |
| [`_display_list_of_paths`](#nemo_gym-cli-env-_display_list_of_paths)                   | -                                                                                                         |
| [`_endpoint_probe_url`](#nemo_gym-cli-env-_endpoint_probe_url)                         | What to GET to find out whether `base_url` is being served.                                               |
| [`_format_pct`](#nemo_gym-cli-env-_format_pct)                                         | -                                                                                                         |
| [`_inspect_environment`](#nemo_gym-cli-env-_inspect_environment)                       | Render the `gym list environments &lt;name&gt;` inspect view for one environment.                         |
| [`_is_dns_failure`](#nemo_gym-cli-env-_is_dns_failure)                                 | Whether a `requests` connection error was a name that does not resolve.                                   |
| [`_model_endpoint_timeout_seconds`](#nemo_gym-cli-env-_model_endpoint_timeout_seconds) | How long to wait for model endpoints, from config. 0 or a negative value skips the check.                 |
| [`_probe_endpoint`](#nemo_gym-cli-env-_probe_endpoint)                                 | Whether anything answers at `base_url`, and if not, whether waiting could help.                           |
| [`_resolve_server_dir`](#nemo_gym-cli-env-_resolve_server_dir)                         | Resolve a relative server dir (e.g. `resources_servers/&lt;name&gt;`) to an absolute path.                |
| [`_select_shard`](#nemo_gym-cli-env-_select_shard)                                     | Deterministically select this shard's subset of modules.                                                  |
| [`_test_single`](#nemo_gym-cli-env-_test_single)                                       | -                                                                                                         |
| [`_validate_data_single`](#nemo_gym-cli-env-_validate_data_single)                     | -                                                                                                         |
| [`_wait_for_model_endpoints`](#nemo_gym-cli-env-_wait_for_model_endpoints)             | Wait for every endpoint to answer. Returns the ones that never did.                                       |
| [`dump_config`](#nemo_gym-cli-env-dump_config)                                         | Display the resolved Hydra configuration for debugging purposes.                                          |
| [`init_resources_server`](#nemo_gym-cli-env-init_resources_server)                     | Initialize a new resources server with template files and directory structure.                            |
| [`list_environments`](#nemo_gym-cli-env-list_environments)                             | List the environments under environments/, or inspect one by name (`gym list environments &lt;name&gt;`). |
| [`pip_list`](#nemo_gym-cli-env-pip_list)                                               | List packages installed in a server's virtual environment.                                                |
| [`prefetch`](#nemo_gym-cli-env-prefetch)                                               | Pre-warm per-server venvs without starting any servers.                                                   |
| [`run`](#nemo_gym-cli-env-run)                                                         | Start NeMo Gym servers for agents, models, and resources.                                                 |
| [`status`](#nemo_gym-cli-env-status)                                                   | -                                                                                                         |
| [`test`](#nemo_gym-cli-env-test)                                                       | -                                                                                                         |
| [`test_all`](#nemo_gym-cli-env-test_all)                                               | -                                                                                                         |
| [`validate`](#nemo_gym-cli-env-validate)                                               | Validate a config without starting Ray or any server subprocess.                                          |

### Data

[`_BASE_URL_KEY_SUFFIX`](#nemo_gym-cli-env-_BASE_URL_KEY_SUFFIX)

[`_DEFAULT_MODEL_ENDPOINT_READINESS_TIMEOUT_SEC`](#nemo_gym-cli-env-_DEFAULT_MODEL_ENDPOINT_READINESS_TIMEOUT_SEC)

[`_ENDPOINT_ANSWERING`](#nemo_gym-cli-env-_ENDPOINT_ANSWERING)

[`_ENDPOINT_POLL_INTERVAL_SEC`](#nemo_gym-cli-env-_ENDPOINT_POLL_INTERVAL_SEC)

[`_ENDPOINT_PROBE_TIMEOUT_SEC`](#nemo_gym-cli-env-_ENDPOINT_PROBE_TIMEOUT_SEC)

[`_ENDPOINT_REFUSED`](#nemo_gym-cli-env-_ENDPOINT_REFUSED)

[`_ENDPOINT_UNRESOLVABLE`](#nemo_gym-cli-env-_ENDPOINT_UNRESOLVABLE)

[`_FORCE_KILL_REAP_TIMEOUT_SEC`](#nemo_gym-cli-env-_FORCE_KILL_REAP_TIMEOUT_SEC)

[`_GRACEFUL_SHUTDOWN_TIMEOUT_SEC`](#nemo_gym-cli-env-_GRACEFUL_SHUTDOWN_TIMEOUT_SEC)

[`_MODEL_SERVER_TYPE`](#nemo_gym-cli-env-_MODEL_SERVER_TYPE)

### API

```python
class nemo_gym.cli.env.PipListConfig()
```

**Bases:** [RunConfig](#nemo_gym-cli-env-RunConfig)

**`format`** `Optional[str]`

---

**`outdated`** `bool`

---

```python
class nemo_gym.cli.env.RunConfig()
```

**Bases:** [BaseNeMoGymCLIConfig](/nemo-gym/nemo_gym/config_types#nemo_gym-config_types-BaseNeMoGymCLIConfig)

Start NeMo Gym servers for agents, models, and resources.

Examples:

```python
config_paths="resources_servers/example_single_tool_call/configs/example_single_tool_call.yaml,\
responses_api_models/openai_model/configs/openai_model.yaml"
gym env start "+config_paths=[${config_paths}]"
```

**`entrypoint`** `str`

---

```python
class nemo_gym.cli.env.RunHelper()
```

**`_head_server`** `Server`

---

**`_head_server_instance`** `HeadServer`

---

**`_head_server_thread`** `Thread`

---

**`_processes`** `Dict[str, Popen]`

---

**`_server_client`** `ServerClient`

---

**`_server_instance_display_configs`** `List[ServerInstanceDisplayConfig]`

---

```python
nemo_gym.cli.env.RunHelper.check_http_server_statuses(
    successful_servers: typing.List[str]
) -> typing.List[typing.Tuple[str, nemo_gym.server_utils.ServerStatus]]
```

```python
nemo_gym.cli.env.RunHelper.display_server_instance_info() -> None
```

```python
nemo_gym.cli.env.RunHelper.poll() -> None
```

```python
nemo_gym.cli.env.RunHelper.run_forever() -> None
```

```python
nemo_gym.cli.env.RunHelper.shutdown() -> None
```

```python
nemo_gym.cli.env.RunHelper.start(
    global_config_dict_parser_config: nemo_gym.global_config.GlobalConfigDictParserConfig
) -> None
```

```python
nemo_gym.cli.env.RunHelper.wait_for_dry_run_spinup() -> None
```

```python
nemo_gym.cli.env.RunHelper.wait_for_model_endpoints(
    global_config_dict: omegaconf.DictConfig
) -> None
```

Block until every model endpoint named in the config answers, then return.

Reads the bound from `model_endpoint_readiness_timeout_seconds`, where 0 skips the check
entirely. Raises `ConfigError` naming the endpoints that never answered and the config key
each came from. It raises rather than exits because `RunHelper` is imported and driven as a
library, so the caller decides what an unreachable endpoint means; the CLI entrypoints turn
it into an exit.

The servers spawned above are shut down first. They hold ports and have neither a process
group nor an atexit handler, and every caller reaches its own `shutdown()` only after
`start()` returns.

```python
nemo_gym.cli.env.RunHelper.wait_for_spinup() -> None
```

```python
class nemo_gym.cli.env.TestAllConfig()
```

**Bases:** [BaseNeMoGymCLIConfig](/nemo-gym/nemo_gym/config_types#nemo_gym-config_types-BaseNeMoGymCLIConfig)

Run tests for all server modules in the project.

Examples:

```python
gym env test
```

**`delete_venvs_after_each_test`** `bool`

---

**`fail_on_total_and_test_mismatch`** `bool`

---

**`num_shards`** `int`

---

**`shard_index`** `int`

---

```python
class nemo_gym.cli.env.TestConfig()
```

**Bases:** [RunConfig](#nemo_gym-cli-env-RunConfig)

Test a specific server module by running its pytest suite and optionally validating example data.

Examples:

```python
gym env test +entrypoint=resources_servers/example_single_tool_call
```

**`_dir_path`** `Path`

---

**`dir_path`** `Path`

---

**`resolved_dir_path`** `Path`

Absolute server dir resolved against the cwd, then the Gym install root.

Use this for filesystem access (reading data, running the suite); use `dir_path` (the
relative entrypoint) for display and example commands shown to the user.

---

**`should_validate_data`** `bool`

---

```python
nemo_gym.cli.env.TestConfig.model_post_init(
    context
)
```

```python
nemo_gym.cli.env._collect_model_endpoints(
    global_config_dict: omegaconf.DictConfig
) -> typing.List[typing.Tuple[str, str]]
```

The upstream model endpoints named in the resolved config, as (config key, url) pairs.

`wait_for_spinup` only polls Gym's own servers, and the Gym-side model server answers as soon
as it starts whether or not anything is behind it, so these are the URLs nothing checks.

`base_url` is typed `Union[str, List[str]]` on vllm\_model and the local vLLM servers, where the
list form spreads load across replicas. The local ones default to an empty list and are filled
in after Gym launches vLLM, so an empty list means "not yet" rather than "misconfigured" and is
skipped, as is an unset value.

The key travels with the url because the endpoint that fails may be a judge or user model, and
a message naming `policy_base_url` would then be wrong.

```python
nemo_gym.cli.env._display_list_of_paths(
    paths: typing.List[pathlib.Path]
) -> str
```

```python
nemo_gym.cli.env._endpoint_probe_url(
    base_url: str
) -> str
```

What to GET to find out whether `base_url` is being served.

`GET /v1/models` is part of the OpenAI API, so most endpoints behind a `/v1` base URL answer it,
but nothing here depends on that: any HTTP response counts as answering, so an endpoint without
it replies 404 and still passes. URLs that do not end in `/v1` are probed at their root.

```python
nemo_gym.cli.env._format_pct(
    count: int,
    total: int
) -> str
```

```python
nemo_gym.cli.env._inspect_environment(
    name: str,
    environments: dict,
    global_config_dict
) -> None
```

Render the `gym list environments &lt;name&gt;` inspect view for one environment.

```python
nemo_gym.cli.env._is_dns_failure(
    error: BaseException
) -> bool
```

Whether a `requests` connection error was a name that does not resolve.

`requests` reports this as a `ConnectionError` like any other, with the resolver failure nested
inside, so the cause chain has to be walked rather than the class inspected.

```python
nemo_gym.cli.env._model_endpoint_timeout_seconds(
    global_config_dict: omegaconf.DictConfig
) -> float
```

How long to wait for model endpoints, from config. 0 or a negative value skips the check.

An unset key falls back to the same default the config parser applies. A value that is not a
number is a configuration mistake, so it is reported as one rather than surfacing as a
`ValueError` traceback from `float()`.

```python
nemo_gym.cli.env._probe_endpoint(
    base_url: str,
    timeout_seconds: float = _ENDPOINT_PROBE_TIMEOUT_SEC
) -> str
```

Whether anything answers at `base_url`, and if not, whether waiting could help.

Answering is the bar, not healthy: a 401 or 404 means something is there, and requiring a 200
would reject endpoints that need auth. A completed TLS handshake counts too, even against a
certificate this process does not trust, which is why `SSLError` is checked before
`ConnectionError` it inherits from.

```python
nemo_gym.cli.env._resolve_server_dir(
    rel_path: pathlib.Path
) -> pathlib.Path
```

Resolve a relative server dir (e.g. `resources_servers/&lt;name&gt;`) to an absolute path.

Searches NEMO\_GYM\_EXTRA\_ROOTS, the current working directory (a user's local server), then the Gym
install root (`PARENT_DIR`) where built-in servers live in both editable and wheel installs. A
directory counts as a server only if it ships an install marker for one of our two venv setups. This
lets `gym env test` find and run built-in (and plugin) servers from any cwd, not just a repo checkout.

```python
nemo_gym.cli.env._select_shard(
    dir_paths: typing.List[pathlib.Path],
    shard_index: int,
    num_shards: int
) -> typing.List[pathlib.Path]
```

Deterministically select this shard's subset of modules.

Round-robin (stride) over a sorted list spreads heavy modules across shards more evenly than
contiguous chunks, which balances wall-time when the suite is parallelized across CI runners.

```python
nemo_gym.cli.env._test_single(
    test_config: nemo_gym.cli.env.TestConfig,
    global_config_dict: omegaconf.DictConfig
) -> subprocess.Popen
```

```python
nemo_gym.cli.env._validate_data_single(
    test_config: nemo_gym.cli.env.TestConfig
) -> None
```

```python
nemo_gym.cli.env._wait_for_model_endpoints(
    endpoints: typing.List[typing.Tuple[str, str]],
    timeout_seconds: float,
    poll_interval_seconds: float = _ENDPOINT_POLL_INTERVAL_SEC,
    monotonic = monotonic,
    sleep_fn = sleep
) -> typing.List[typing.Tuple[str, str]]
```

Wait for every endpoint to answer. Returns the ones that never did.

Unresolvable names are reported once and not waited on. Refused connections are waited on,
because an inference server can take minutes to load weights and someone who starts thirty
seconds early should not have to start over.

```python
nemo_gym.cli.env.dump_config()
```

Display the resolved Hydra configuration for debugging purposes.

Examples:

```python
gym env resolve "+config_paths=[<config1>,<config2>]"
```

```python
nemo_gym.cli.env.init_resources_server()
```

Initialize a new resources server with template files and directory structure.

Examples:

```python
gym env init --resources-server my_server
```

```python
nemo_gym.cli.env.list_environments() -> None
```

List the environments under environments/, or inspect one by name (`gym list environments &lt;name&gt;`).
Optionally filtered by a `query` (the `gym search environments` entry point). `--search-dir` adds extra
roots on top of the cwd and built-ins.

Examples:

```python
gym list environments
gym list environments calendar
gym list environments --json
gym list environments --search-dir /path/to/project
```

```python
nemo_gym.cli.env.pip_list()
```

List packages installed in a server's virtual environment.

```python
nemo_gym.cli.env.prefetch(
    global_config_dict_parser_config: typing.Optional[nemo_gym.global_config.GlobalConfigDictParserConfig] = None
)
```

Pre-warm per-server venvs without starting any servers.

Accepts the same config format as 'gym env start'. For each server in the config,
creates its isolated venv and installs dependencies serially — similar to how
RL's prefetch\_venvs.py installs actor venvs at container build time.

No Ray is initialised and no server processes are started. Intended for use in
Dockerfile builds so venvs are ready at runtime with no network access needed.

Examples:

```python
# Pre-warm venvs for a specific config
config_paths="responses_api_models/local_vllm_model/configs/local_vllm_model.yaml,\
resources_servers/math/configs/math.yaml"
gym env prefetch "+config_paths=[${config_paths}]"
```

```python
nemo_gym.cli.env.run(
    global_config_dict_parser_config: typing.Optional[nemo_gym.global_config.GlobalConfigDictParserConfig] = None
)
```

Start NeMo Gym servers for agents, models, and resources.

This command reads configuration from YAML files specified via `+config_paths` and starts all configured servers.
The configuration files should define server instances with their entrypoints and settings.

Examples:

```python
# Start servers with specific configs
config_paths="resources_servers/example_single_tool_call/configs/example_single_tool_call.yaml,\
responses_api_models/openai_model/configs/openai_model.yaml"
gym env start "+config_paths=[${config_paths}]"
```

```python
nemo_gym.cli.env.status()
```

```python
nemo_gym.cli.env.test()
```

```python
nemo_gym.cli.env.test_all()
```

```python
nemo_gym.cli.env.validate()
```

Validate a config without starting Ray or any server subprocess.

Runs the full config parse — config\_paths resolution (missing/malformed), server cross-reference
validation, mandatory `???` values, and schema — then exits 0 (valid) or, via
`exit_cleanly_on_config_error`, 1 with a clean traceback-free message. No Ray, no servers, so it
returns in well under a second instead of after Ray bootstrap.

No model config is required: a dummy `policy_model` is injected (the `NO_MODEL` parser config, as
in `gym list` / `env compose`) so model interpolations (e.g. `$&#123;policy_base_url&#125;`) resolve —
validation is about config well-formedness, not the model. Pass a model config / `--model-type`
as well if you want it validated too.

Examples:

```python
gym env validate --environment <env>
gym env validate --benchmark <benchmark>
# or by explicit config path(s):
gym env validate --config resources_servers/<env>/configs/<env>.yaml
```

```python
nemo_gym.cli.env._BASE_URL_KEY_SUFFIX = 'base_url'
```

```python
nemo_gym.cli.env._DEFAULT_MODEL_ENDPOINT_READINESS_TIMEOUT_SEC: float = 600.0
```

```python
nemo_gym.cli.env._ENDPOINT_ANSWERING = 'answering'
```

```python
nemo_gym.cli.env._ENDPOINT_POLL_INTERVAL_SEC: float = 3.0
```

```python
nemo_gym.cli.env._ENDPOINT_PROBE_TIMEOUT_SEC: float = 5.0
```

```python
nemo_gym.cli.env._ENDPOINT_REFUSED = 'refused'
```

```python
nemo_gym.cli.env._ENDPOINT_UNRESOLVABLE = 'unresolvable'
```

```python
nemo_gym.cli.env._FORCE_KILL_REAP_TIMEOUT_SEC: int = 2
```

```python
nemo_gym.cli.env._GRACEFUL_SHUTDOWN_TIMEOUT_SEC: int = 1
```

```python
nemo_gym.cli.env._MODEL_SERVER_TYPE = 'responses_api_models'
```