Skip to main content
The pluto.query submodule exposes read helpers for fetching run data without writing your own HTTP client, plus one write helper — upload_file — for attaching a file to a run after the fact. Use these when you want to pull metrics into a notebook, compare runs in a script, download artifacts from a finished training job, or attach an artifact to a run from outside the training process. For the underlying HTTP API, see the API Reference. Every helper that takes a run ID accepts either a numeric ID (e.g. 12345) or a display ID (e.g. "MMP-42").

Helpers

All helpers raise on the network or auth error path; otherwise they return parsed Python objects (upload_file returns None on success). Authentication is resolved from PLUTO_API_KEY or your saved login. Self-hosted deployments also need PLUTO_URL_INGEST set for upload_file, since it uploads through the ingest service rather than the main API — a bare host argument maps to http://{host}:3003.

Uploading a file to an existing run

pluto.query.upload_file attaches one file artifact to an existing run over plain HTTP — a presigned upload through the ingest service. It never creates a run handle and never touches the run’s lifecycle or metadata: no status changes, no systemMetadata writes, no sys/* metrics from the machine that calls it. That’s the key difference from pluto.init(resume=True), which reopens the run for writing and, as a side effect, overwrites its systemMetadata with the resuming machine’s environment, injects that machine’s sys/* metrics, and marks a live run terminal at interpreter exit. upload_file has none of those side effects, which makes it safe to call from a laptop, a CI job, or any machine other than the one that ran the training — against a run that’s still live.
The same call is also the recovery path when the training client itself reports a file as unsent — see Upload reliability and recovery:
On failure — a rejected upload, or a local path that doesn’t exist — upload_file raises pluto.query.QueryError with the server’s reason.

Filtering runs

The API for filters is currently in preview. The API may change at any moment. Check in frequently for updates. Have feedback? Let’s get in touch at founders@trainy.ai
list_runs accepts a filters argument with a query language. It composes boolean logic ($and / $or / $not) over conditions over run configurations/status/staleness. Consider the following example that checks for runs that haven’t COMPLETED and haven’t reported any metrics in the past hour.

Operators

Fields

More examples

filters AND-combines with search, tags, and sort on the same call, and pages with limit / offset.
Filtering on heartbeat_at or summaryMetrics.*, and any $or / $not, require a project (they’re scoped to a single project). Unknown fields or operators return a 400.