Python SDK reference
The public entrypoint is from envloop import Client. Methods synchronously return dictionaries; use keyword arguments as documented below. The server remains responsible for validation and execution. See Python SDK guide for installation and usage.
Client
| Method | Behavior |
|---|---|
Client.remote(api_url=None, *, timeout=30, api_key=None, workspace_id=None) | Create an HTTP client; omitted configuration is read from the system environment, not .env.local |
Client.local(*, work_dir=None, repository_root=None, repository_commit=None) | Create and manage an in-process LocalServer; requires optional EnvPlatform |
Client(server) | Use a caller-managed service; server is required |
Client.init_repository(root) | Initialize the local registry without changing Git; returns None |
client.close() | Locally wait for the owned service to close; remotely do not stop platform tasks |
Context managers are supported. Remote timeout is the deadline for each HTTP request; tasks/jobs wait timeout is the client's total waiting deadline. A repository without an explicit commit is fixed to local main.
Tasks
client.tasks.submit(
source=None,
*,
request_id=None,
runner=None,
dataset=None,
task_id=None,
namespace=None,
config=None,
split=None,
revision=None,
profile_id=None,
job_id=None,
tag=None,
queue_id="default",
priority=0,
profile=None,
task_ref=None,
profile_name=None,
profile_version=None,
profile_sha256=None,
profile_overrides=None,
seed=None,
execution=None,
command=None,
)
| Parameter | Behavior |
|---|---|
source | Two-file directory str / Path, or file-content Mapping |
runner / dataset | Named runner and Dataset name or selector Mapping; mutually exclusive with source / task_ref |
task_id | One Task in the Dataset; can also be placed in the dataset selector |
namespace / config / split / revision | Dataset selection; conflicting selector fields raise ValueError |
profile_id | APIServer immutable Profile ID |
job_id / tag | Optional Job ownership and run tag |
queue_id / priority | Defaults default / 0; higher priority dispatches waiting tasks sooner |
request_id | Nonempty string; generates a UUID if omitted; retries reuse the first execution |
profile | Inline parameter Mapping interpreted by the Task |
task_ref | Fixed platform task-reference Mapping supplied by matching repository / Dataset APIs; not a bare task_name or URL |
profile_name / profile_version | Server-side named Profile; omitting version requires an explicit default |
profile_sha256 | Expected normalized ProfileSpec hash |
profile_overrides | Parameter override Mapping |
seed | Seed override |
execution | Execution override Mapping, for example {"timeout_sec": 60} |
command | Optional nonempty UTF-8 shell script, at most 65536 bytes, no NUL; executed verbatim in the Runner working directory |
Most users should prefer source; a fixed task_ref requires a corresponding platform snapshot. Do not pass both task contents and a fixed reference. The platform validates inline and named Profile combinations; do not mix them to guess precedence. submit returns a status dictionary containing trial_id.
Named runner submission uses HTTP /v1/trials. An example Dataset selector is {"name": "org/benchmark", "version": "1", "task_id": "org/task"}; the string org/benchmark@1 also works with task_id. APIServer handles authorization, catalog resolution, freezing, and execution; the SDK does not read task directories. Legacy two-file submissions continue using /v1/tasks. LocalServer / JobMaster without a catalog rejects unresolved named runner requests.
| Method | Return / behavior |
|---|---|
tasks.status(trial_id) | Status details, including terminal state, exit code, or error fields |
tasks.wait(trial_id, *, timeout=30, poll_interval=0.05) | Return final status; terminal states succeeded / failed / cancelled |
tasks.result(trial_id) | stdout, stderr, outputs; does not automatically wait |
tasks.snapshot(trial_id) | Frozen input snapshot |
tasks.stop(trial_id) | Stop-request response; support depends on the execution backend |
wait requires a finite nonnegative timeout and a finite positive poll_interval. A timeout raises TimeoutError without cancelling the run; execution failure returns failed status. Directory-read and platform validation errors propagate separately.
Jobs
client.jobs.submit(
dataset,
*,
request_id=None,
attempts=1,
namespace=None,
config=None,
split=None,
revision=None,
runner=None,
profile_id=None,
job_id=None,
tag=None,
queue_id="default",
priority=0,
command=None,
**options,
)
dataset is a name, name@version, or fixed dataset_ref Mapping. With a runner, it also accepts a Dataset selector Mapping without kind. Selection options cannot be combined with a fixed dataset_ref. runner is name or name@version; profile_id, job_id, and tag are optional, queue_id defaults to default, and priority defaults to 0, with higher values dispatching waiting tasks sooner. options passes platform submission fields such as profile_name, profile_version, seed, and execution; this does not imply that arbitrary fields are supported. submit returns a dictionary containing job_id. All selections are sent through /v1/jobs for platform resolution; the client does not freeze the catalog.
command overrides the default Runner script for every member, with the same validation as Task. By default, Runner execution.command is used; if absent, the entrypoint determines bash main.sh or python main.py. Source directories contain runner.toml by default; legacy task.toml is supported, but both configurations together are rejected.
| Method | Return / behavior |
|---|---|
jobs.status(job_id) | Status details |
jobs.wait(job_id, *, timeout=600, poll_interval=0.1) | Return final status, completed / failed / cancelled |
jobs.result(job_id) | Job aggregate results; wait does not replace this method |
jobs.list(**kwargs) | Paginated results; common options limit and cursor, HTTP default limit 25 |
jobs.stop(job_id) | Cancellation-request response |
Job wait has the same numeric constraints as Task wait; timeout does not automatically cancel.
Profiles
These methods implement the local Profile management contract; HTTP management is not implemented.
| Method | Behavior |
|---|---|
profiles.init(root) | Initialize the repository registry |
profiles.put(spec) / profiles.create(spec) | Save a complete ProfileSpec Mapping |
profiles.get(name, version=None) | Get a version / default |
profiles.list(**kwargs) | name, include_archived, limit (default 50), cursor |
profiles.resolve(name, version=None, expected_sha256=None) | Resolve and validate a version |
profiles.set_default(name, version, *, expected_version) | Update the default; pass expected_version=None for the first setting |
profiles.archive(name, version) | Archive |
profiles.export(name, version) | Export bytes |
profiles.import_spec(raw, *, name=None, version=None) | Import JSON bytes, optionally checking name and version |
See Profiles guide for examples.
Errors and result interpretation
SDK wait does not convert a failed terminal state into an exception. Timeout raises TimeoutError; client input may raise ValueError, filesystem, or TOML errors. Local platform TaskError may provide status_code; remote errors use sanitized codes. Do not depend on private client members or arbitrary error bodies.
Successful status, successful commands, and verifier reward=1 are separate conclusions; use actual results for scoring. There is currently no client.train or asynchronous Client factory.