Metadata-Version: 2.5
Name: envloop-cli
Version: 1.32.0
Summary: EnvLoop CLI and Python SDK for jobs, training, checkpoints and inference
Project-URL: Homepage, https://envloop.ai
Project-URL: Documentation, https://docs.envloop.ai
Project-URL: Repository, https://github.com/EnvLoop/envloop-cli
Project-URL: Issues, https://github.com/EnvLoop/envloop-cli/issues
Project-URL: Agent instructions, https://docs.envloop.ai/skill.md
Requires-Python: >=3.12
Provides-Extra: data
Requires-Dist: envloop-envhub==1.23.0; extra == 'data'
Provides-Extra: default
Provides-Extra: experiment
Provides-Extra: rsi-loop
Description-Content-Type: text/markdown

# envloop-cli: EnvLoop CLI and Python SDK

Install the public client to run agent Jobs, inspect Trials, manage training and
checkpoints, and deploy or call inference endpoints. The `el` and `envloop`
commands are equivalent. The Python import package is `envloop`.

## Version 1.7

- Use published Runner resource shortcuts for Train Jobs and fixed Checkpoint inputs for Inference Jobs.
- Pass `--json` explicitly to `job submit`; failures retain safe error codes and recovery guidance.
- Submit training through Train Jobs. The retired interactive `envloop.training` interface is removed.

After upgrading, check `el --version` and `el job submit --help`. Execution also
requires a matching platform, project permissions and published Runners; package
installation alone does not establish those prerequisites. See the
[PyPI release history](https://pypi.org/project/envloop-cli/#history) for published versions.

## Install

envloop-cli requires Python 3.12 or later; an existing compatible interpreter can
be reused. The following [uv](https://docs.astral.sh/uv/) example uses Python 3.12:

```bash
uv tool install --python 3.12 envloop-cli
el --version    # upgrade later with: uv tool upgrade --python 3.12 envloop-cli
el --help
```

To use the Python SDK, install the package into a Python 3.12+ virtual environment:

```bash
uv venv --python 3.12
uv pip install --upgrade envloop-cli
# or, with an existing Python 3.12 interpreter:
python3.12 -m pip install --upgrade envloop-cli
```

Every installation includes Jobs, Trials, training, logs, inference calls, Data resources, checkpoints and RSI Loop controls.
Check that the SDK can be imported:

```bash
python -c 'from envloop import Client; print("EnvLoop SDK ready")'
```

When you see `EnvLoop SDK ready`, continue to Connect. This check imports the
client without creating a Job. Submit training through `client.training_jobs`;
follow the [managed training guide](https://docs.envloop.ai/training/cli-hello-world).

Install the client in your Python environment; the platform provides the execution resources.

## Optional features

One `envloop-cli` wheel and source archive contain all feature code. Extras add dependencies only:

```bash
python -m pip install envloop-cli
python -m pip install "envloop-cli[data]"
python -m pip install "envloop-cli[data,experiment,rsi-loop]"
```

Every installation includes the existing Job, Trial, Data and RSI Loop commands. The bare installation and `default`, `experiment`, `rsi-loop` groups have no runtime dependencies. `data` adds `envloop-envhub==1.23.0` for ANS parsing and verified directory downloads. Other Data API operations use the bundled client implementation. Missing ANS dependencies produce the `envloop-cli[data]` installation instruction.

Feature modules load lazily. Default imports, help and experiment operations do not require EnvHub or certifi. Only the single `envloop-cli` distribution owns the `el` / `envloop` scripts. The examples below require an authorized matching platform; installation does not grant permissions.

Versions 1.23.0 and 1.24.0 on PyPI depend on feature packages that were never published: their `data` extra cannot be installed and the DATA command group is empty. They also install a separate `envloop-cli-experiment` package that shares files with this release. Remove both before installing; uninstalling `envloop-cli-experiment` after an upgrade deletes files the client needs and leads to `FEATURE_NOT_INSTALLED`, which the same commands repair:

```bash
python -m pip uninstall -y envloop-cli envloop-cli-experiment
python -m pip install "envloop-cli[data]"
```

## Connect

Use an authorized EnvLoop account and project. Browser authorization:

```bash
el auth login
el auth status --check
```

For an existing project API key, use the masked configuration wizard:

```bash
el auth config
el auth status --check
```

CI can read credentials from `ENVLOOP_API_KEY` and connection settings from
`ENVLOOP_BASE_URL`, `ENVLOOP_WORKSPACE_ID` and `ENVLOOP_PROJECT_ID`. Keep keys in
your secret manager. Public API access is scoped to the authorized project.

Credentials and settings live in `~/.envloop` (override with an absolute
`ENVLOOP_HOME`). On POSIX the directory must be private and owned by you. Use the
default path when the optional environment variable is unset:

```bash
mkdir -p "${ENVLOOP_HOME:-$HOME/.envloop}"
chmod 700 "${ENVLOOP_HOME:-$HOME/.envloop}"
```

An insecure directory causes `el` to fail with `CONFIG_INSECURE_PATH`.

## Errors

Errors go to stderr as an error code, a short explanation and the applicable
HTTP status, without a Hint. Interactive terminals use a red heading and a dim
HTTP status. Redirected output, pipes, `TERM=dumb`, or a nonempty `NO_COLOR`
disable color. `--json` stdout remains JSON.

```text
Error: PROFILE_NOT_FOUND
  The Profile was not found or is not readable in the current scope.
  HTTP 404
```

## Explore your project

```bash
el job list --limit 5
el job list --type train --limit 5
el trial list --limit 5
el trial list --type train --job-id JOB_ID
el checkpoint list --limit 5
el job list --type inference
```

Query a returned Job ID with `el job get JOB_ID` and `el job result JOB_ID`.
Trial commands use `el trial`, for example `el trial artifact list TRIAL_ID`. Use each command's `--help` for options.

For the Python SDK:

```python
from envloop import Client

with Client.remote() as client:
    print(client.jobs.list(limit=5))
    print(client.trials.list(type="train", limit=5))
```

Submitting work, training a model or starting inference can allocate billable
resources. Follow the task-specific guide and retain the outputs you need before
cleaning up temporary resources.

## Sandbox jobs

After `el auth login`, you may reuse an existing EnvPlatform Profile as an
optional preset. It uses the current login and project permissions. Submit its
published name and optional ANS input bindings or declared parameters:

```bash
el job submit --type sandbox --profile team/report@1 --input report=ARTIFACT_URI --params Mode=Summary --max-cost-usd 3
```

The platform resolves and freezes the Runner and inputs, and manages any model
service declared by the Profile. No local script, Dataset Task wrapper or Runner
argument is required. Use a published Artifact URI in place of `ARTIFACT_URI`.
`--profile` and `--spec` are mutually exclusive. Named Profile parameter names
retain their case and duplicates are rejected.

With a matching platform and a published `envloop/base` ANS Runner, submit a
Sandbox Job without a Dataset:

```bash
el job submit --type sandbox --runner base --command 'python --version'
el job submit --type sandbox --runner base --image python:3.11 --wait
el job list --type sandbox
el job log JOB_ID --follow
```

The platform resolves `base` to the registered `envloop/base@main` source ref and
freezes its immutable Revision. The Sandbox image defaults to `python:3.11`;
`--image` accepts an image name, tag or digest. The execution provider is configured
by the server. Job logs retain the actual captured output and collection metadata.
Failures include a code, readable explanation, HTTP status when available, and
recovery guidance without echoing arbitrary response bodies or credentials.

## Existing installations

This distribution provides both the CLI and the `envloop` import package. Use a
fresh environment if you previously installed the separate source distribution
named `envloop`, so two distributions do not own the same Python module files.
Existing client configuration is reused; installing a package does not change
your account permissions or move remote resources. Check `el --help` when
upgrading because command groups may differ from your earlier installation.

## Documentation

- [English documentation](https://docs.envloop.ai/)
- [中文文档](https://docs.envloop.ai/zh-cn/)
- [Installation](https://docs.envloop.ai/cli-install)
- [CLI reference](https://docs.envloop.ai/reference/cli)
- [Training and deployment](https://docs.envloop.ai/training/train-deploy)
- [Agent entry: skill.md](https://docs.envloop.ai/skill.md)

## Submit managed training

Prepare a recipe-supported `REQUEST.json` using the [SFT quickstart](https://docs.envloop.ai/training/quickstart).
Training uses billable resources. Check your project permissions, balance and data format, then submit once:

```bash
el job submit --type train --spec REQUEST.json
el job get JOB_ID
el job log JOB_ID --follow
el job result JOB_ID
el checkpoint list --job-id JOB_ID
```

`job submit --spec` reads the complete Job specification JSON file for Train or Inference.
The former `job submit --file` option is removed; the JSON payload is unchanged.

Replace `JOB_ID` with the receipt's value. Read the training status and logs, then find the registered checkpoint after success.
Ctrl-C ends log reading; to stop training, use `el job stop JOB_ID` and check its state and resource cleanup.
See [Checkpoints](https://docs.envloop.ai/training/checkpoints) to download or delete saved weights.

The built-in SFT recipe does not support custom loss, RL or optimizer-state resume.
For an older interactive training script, follow the [managed training migration](https://docs.envloop.ai/training/sdk-compatibility).

## Run a GPU Runner

Choose a published Runner readable in your project. Save this request as `gpu-run.json`, replacing `FULL_COMMIT` with the full Revision from `el runner list --json`:

```json
{
  "request_id": "gpu-run-001",
  "trials": [
    {"name": "first", "spec": {"runner": "envloop/bash@FULL_COMMIT", "resources": {"gpu_type": "H100", "gpus": 4}, "timeout_seconds": 600}},
    {"name": "second", "spec": {"runner": "envloop/bash@FULL_COMMIT", "resources": {"gpu_type": "H100", "gpus": 4}, "timeout_seconds": 600}}
  ]
}
```

```bash
el job submit --type train --spec gpu-run.json
el job get JOB_ID
el job log JOB_ID --follow
el job result JOB_ID
```

Replace `JOB_ID` with the returned value. The example has two independent Trials, each requesting four H100 GPUs: concurrent execution needs eight GPUs. Capacity and budget determine actual concurrency. Startup and execution are billable; check the Runner requirements, project `training.run` permission, and applicable prices and balance in your authorized Console account first. Reduce the Trial or GPU count when your program supports a smaller first run. The [usage guide](https://docs.envloop.ai/manage/usage) explains resource observations.

The request file does not depend on GPU shortcut flags. If `el job submit --help` lists both `--trials` and `--gpu-type`, you can instead use the shortcuts in [GPU Runner training](https://docs.envloop.ai/training/runner). Choose one submission method to avoid duplicate runs. The SDK accepts the same dictionary through `client.training_jobs.submit(request)`.

The platform starts the published Revision’s `main.sh` / `main.py` using the Runner image; it does not upload local code. An optional command can only supply a declared `run_command` parameter. If this mode or GPU type is unavailable, contact your project administrator. Use `el job stop JOB_ID` to stop every Trial, then inspect each Trial’s `cleanup_confirmed` and download the uploaded artifacts you need.


CLI output uses compact timestamps and highlights statuses and log levels by default on terminals.
Use `el --no-color job list` or append `--no-color` to a command to disable highlighting, including errors.
`NO_COLOR=1`, `TERM=dumb`, pipes, and redirected output also disable colors. JSON preserves original values.
List and table times are UTC with a `UTC` label; Job logs retain the recorded timezone and mark lines collected only after the Job ended with `(backfilled)`. Full precision, offsets and the `backfilled` field are available through `--json`.
`el job run live RUN --follow --json` emits complete response frames as NDJSON; Ctrl-C stops reading without stopping the Run.

## Job-bound decision plugins

When the platform and published Runner support Job Profiles, include the authorized
`profile` snapshot in the Train or Inference request's `spec`. The platform freezes
its inputs, recipe and approved plugin pins. This does not select an executor or provider.

For an Inference Job with a bound decision plugin, save the plugin payload as JSON:

```bash
el job decision JOB_ID --model WORKSPACE/MODEL --spec payload.json
```

```python
with Client.remote() as client:
    result = client.decision.evaluate(
        "JOB_ID", model="WORKSPACE/MODEL", payload=payload
    )
```

Use the exact model returned by the Job. The SDK forwards the payload to the
Job's `/inference/decision` API; the approved plugin validates its business fields.
Availability requires matching platform support and approved content in your project.

## ANS data and verified downloads

`client.data.download_directory(uri, destination)` and `el data download DATA_ID|URI --output ./content`
download a complete registered ANS object directory through EnvHub. Datasets require
`split="lite"` / `--split lite` (the error lists the declared splits); the Dataset version and filenames are preserved. After API
authorization the SDK uses GET URLs valid for up to five minutes, verifies file size/SHA-256,
and installs the directory atomically. Matching platform support is required.

A compatible server is required. Data uses the permission of the resource it touches: read (for example `datasets.read`) to query and download, write to publish and upload, delete to retire; a key from `el auth login` follows your project role. The current login selects the base URL, workspace and project; there is no `--env` flag. After configuring the Key using `el auth config`:

```bash
el data list --type dataset --json
el data get DATA_ID --json
el data download DATA_ID --file FILE_ID --output ./dataset.tgz --resume --json
```

Unified ANS CRUD supports Dataset, Runner, Recipe and HF model Checkpoint registrations through `el data` and `client.data`. Dataset/Runner/Recipe creation requires a native `--manifest` and exact `--directory`. For Dataset create/update/upload, `--ref` (SDK `ref`) is optional when `dataset.namespace`, `dataset.name` and `dataset.version` are present in the manifest; EnvHub derives the immutable Dataset URI. Other resource types and manifests without that identity still require an explicit ref. Explicit refs remain supported; the platform validates their consistency with the manifest. HF metadata registration uses `el data create --type checkpoint --model namespace/model --revision FULL_COMMIT`; SDK uses `create(kind="checkpoint", model=..., revision=...)`. HF weights are not downloaded, and artifact imports do not establish Model or Job checkpoint provenance. While native publication runs, `create`/`update` repeat the same idempotent request until ready (`--timeout`, default 3600 s); `--no-wait` / `wait=False` returns the pending `publishing` resource with resume instructions.

`el runner register DIRECTORY --revision FULL_COMMIT [--source-ref main]` publishes a Runner package directory through the same Data API with the manifest built for you, then reads the catalog revision back. `el profile create|update|fork ... --secret NAME[=prompt|stdin|env:VAR|file:PATH]` stores write-only Secret parameters whose names follow the platform's credential rule or `secret_params`; values never come from the command line. `el setting model-access grant NAMESPACE/NAME --protocol anthropic [--revision FULL_COMMIT]` (project Admin) lets a published Runner receive the project's metered model key on Fly Trials; `list` and `revoke GRANT_ID` manage grants.

Success follows native storage and original catalog readback and returns an `ans_` identity. Update publishes an explicit new revision. Delete checks active and unknown dependencies; Runner deletion covers all revisions. Historical bytes and quota usage remain. Commands default to the current login base URL/workspace/project, with no `--env`. Both Data grants and the corresponding resource capabilities are required.

Read methods include `list/get/files/open/download`; `client.recipes.list/get` queries the original Recipe catalog. Downloads verify size/SHA-256 and refuse existing destinations, symlinks and storage redirects. Large payloads use multipart with stable idempotency keys. Staging `pub_` IDs and failure phases support retry; they are not native success. Matching client/server support is required. See the [Data reference](https://docs.envloop.ai/reference/cli#data-commands).
