Metadata-Version: 2.5
Name: envloop-cli
Version: 1.31.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

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 URI --output ./content`
download a complete registered ANS object directory through EnvHub. Datasets require
`split="lite"` / `--split lite`; 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 immutable `--ref`, `--manifest` and exact `--directory`. 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.

`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).
