Job

Client for managing asynchronous jobs and status tracking.

For usage examples and guides, see Data API on docs.ionworks.com.

Job client for managing asynchronous jobs.

This module provides the JobClient for submitting, monitoring, and managing background jobs in the Ionworks platform.

class ionworks.api.job.JobCreationPayload(*, job_type: str, params: dict[str, Any], priority: int = 5, callback_url: str | None = None)[source]

Bases: BaseModel

Payload for creating a job.

job_type: str
params: dict[str, Any]
priority: int
callback_url: str | None
model_config = {}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class ionworks.api.job.JobResponse(*, job_id: str, status: str, job_type: str, priority: int, created_at: str, updated_at: str, error: str | None = None, result: dict[str, Any] | None = None, is_terminal: bool, is_failed: bool, **extra_data: Any)[source]

Bases: BaseModel

Response model for job details.

Extra fields are retained so additive backend response fields remain available without requiring a lock-step SDK release.

model_config = {'extra': 'allow'}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

job_id: str
status: str
job_type: str
priority: int
created_at: str
updated_at: str
error: str | None
result: dict[str, Any] | None
is_terminal: bool

the job has reached a terminal state and will not transition further. Read from the wire so the client never needs to hard-code which status strings count as terminal.

Type:

Server-derived flag

is_failed: bool

the job terminated unsuccessfully (failed or canceled). is_terminal and not is_failed means successful completion.

Type:

Server-derived flag

class ionworks.api.job.JobClient(client: Any)[source]

Bases: object

Client for managing asynchronous jobs.

This class provides methods to retrieve, list, and cancel jobs in the Ionworks platform. Jobs are started by the client for each kind of work.

__init__(client: Any) → None[source]

Initialize the JobClient.

Parameters:

client (Any) – The HTTP client instance used for API requests.

create(payload: JobCreationPayload) → JobResponse[source]

Submit a job using the provided payload.

Deprecated since version The: server no longer accepts direct job submissions, so every call fails with a 410 error. Start work through the dedicated clients instead: client.pipeline for fits and validations, client.simulation for simulations, and client.ecm for ECM fits. get, list and cancel are unaffected.

Parameters:

payload (JobCreationPayload) – The configuration for the job to be created.

Returns:

Response containing the job_id and initial status.

Return type:

JobResponse

Raises:
  • requests.exceptions.RequestException – If the API request fails.

  • ValueError – If the response parsing fails.

get(job_id: str) → JobResponse[source]

Get the status and details of a specific job.

Parameters:

job_id (str) – The ID of the job to retrieve.

Returns:

Job details and current status.

Return type:

JobResponse

Raises:

ValueError – If the response parsing fails.

get_metadata(job_id: str) → dict[str, Any][source]

Get the full metadata blob for a job.

The parsed JSON of the job’s metadata storage object, including the historic validation_results and baseline_validation_results keys, plot config, and intermediate_results (see get_parameter_trace()). Validation series are materialized from their per-objective parquet files for compatibility, so this call can be expensive. Prefer Pipeline.get_element_series_channels() and Pipeline.get_element_series() for bounded reads.

Parameters:

job_id (str) – The ID of the job whose metadata to retrieve.

Returns:

The parsed metadata payload.

Return type:

dict[str, Any]

get_plot_data(job_id: str, objective_name: str, plot_index: int = 0, max_points: int = 2000, x_min: float | None = None, x_max: float | None = None) → dict[str, Any][source]

Get decimated model-vs-data plot traces for a data-fit job.

Wraps GET /pipelines/datafits/{job_id}/plot_data. A data-fit job re-runs a validation on its best-fit parameters and stores the overlay in its own metadata, so this returns the fit’s model-vs-data traces directly — no separate validation element or raw-metadata polling required. Traces are downsampled to at most max_points points; refetch with x_min / x_max set to the current viewport for semantic zoom.

Parameters:
  • job_id (str) – The data-fit job whose plot data to fetch.

  • objective_name (str) – Objective name within the job’s validation_plot_config (the key used for the objective in the DataFit’s objectives mapping).

  • plot_index (int, optional) – Index into the objective’s list of plots. Defaults to 0.

  • max_points (int, optional) – Maximum points returned per trace (100-80000). Defaults to 2000.

  • x_min (float, optional) – Lower x-range bound (inclusive). Omit for the full range.

  • x_max (float, optional) – Upper x-range bound (inclusive). Omit for the full range.

Returns:

The decimated plot-data payload for the requested plot.

Return type:

dict[str, Any]

get_series_channels(job_id: str) → dict[str, dict[str, list[str]]][source]

List a job’s validation-series objectives and the channels each carries.

Wraps GET /jobs/{job_id}/series/channels. Names only, no samples. Call this before get_series() to learn the objective names, the channel names, and which of the two solves each objective has.

Parameters:

job_id (str) – The data-fit, validation, or optimization job to describe.

Returns:

{objective: {source: [channel, ...]}}, where source is "optimal" or "baseline". Only genuine per-sample channels appear, so a scalar recorded beside the series is not listed. Empty when the job recorded none.

Return type:

dict[str, dict[str, list[str]]]

get_series(job_id: str, objective: str, source: str = 'optimal', columns: list[str] | None = None, x_column: str | None = None, max_points: int | None = None, x_min: float | None = None, x_max: float | None = None) → dict[str, list][source]

Get one objective’s model-vs-data series, windowed and downsampled.

Wraps GET /jobs/{job_id}/series. Reads one objective’s stored series rather than the whole job metadata, so the cost is set by the objective asked for rather than by the size of the fit. The window is applied before the row budget, so the points returned are spent on the range asked for.

Parameters:
  • job_id (str) – The job whose validation series to read.

  • objective (str) – Objective name — a key of the mapping get_series_channels() returns.

  • source (str, optional) – Which solve to read: "optimal" (default) or "baseline".

  • columns (list of str, optional) – Channels to return besides x_column. Defaults to every channel the objective carries. Sent as one comma-separated parameter, so a channel whose name contains a comma cannot be requested.

  • x_column (str, optional) – Channel plotted on x, and therefore the one windowed and binned on. Defaults to the objective’s own x — "Time [s]" for a time-domain fit, "Frequency [Hz]" for an impedance one — so it rarely needs setting.

  • max_points (int, optional) – Row ceiling for the response. Omit to return the window whole, which is the only way to be certain nothing was decimated: the completeness header the browser reads is not exposed here.

  • x_min (float, optional) – Window lower bound, in the units of x_column. Omit for the full range.

  • x_max (float, optional) – Window upper bound, in the units of x_column. Omit for the full range.

Returns:

One list per channel, all of equal length, keyed by channel name.

Return type:

dict[str, list]

Raises:

IonworksError – If source, objective, x_column, or a requested column is not present on the job.

get_parameter_trace(job_id: str) → list[dict[str, Any]][source]

Get the per-iteration parameter trace for a datafit or optimization job.

Datafit and optimization runs log the optimizer’s progress to the job metadata under intermediate_results — one entry per saved iteration. This is the same data the web UI plots as parameter and cost-convergence traces. Each entry contains:

  • best_costfloat

    Best (lowest) objective value seen up to this iteration.

  • costfloat

    Objective value at this iteration.

  • inputsdict

    Scaled parameter values at this iteration.

  • inputs_unscaleddict

    Unscaled (physical) parameter values at this iteration — keyed by parameter name. Use these for parameter traces.

  • multistart_job_idint

    Index of the multistart this entry belongs to, when applicable.

  • outputs / best_outputsdict, optional

    Model outputs at this iteration, present for design-objective runs.

Saves are throttled (roughly every 100 iterations or every 5 seconds), so the trace is a sampled subset of the optimizer’s evaluations rather than every single one, and is empty when live progress updates were disabled for the run. There is no per-iteration wall-clock timing.

Parameters:

job_id (str) – The ID of the datafit or optimization job whose trace to retrieve.

Returns:

The per-iteration trace entries, ordered oldest first. Empty if the job recorded no intermediate results.

Return type:

list[dict[str, Any]]

get_posterior_samples(job_id: str) → dict[str, Any][source]

Get the sample chain for a sampler-based datafit job.

A datafit run with a sampler (e.g. PintsSampler) evaluates many parameter vectors rather than converging on a single point estimate. The full chain is too large for the job result column, so it is offloaded to the job metadata blob, returned here as:

  • samplesdict[str, list]

    The chain, keyed by parameter name. Each value is nested (starts, iterations) for a multistart fit and a flat per-iteration list for a single start, so index the iteration axis last ([..., burnin:]) to handle both.

  • sample_costslist

    The cost/objective value for each sample, shaped like one parameter’s chain.

  • sample_param_nameslist[str]

    The parameter names in column order.

  • sample_burninint or None

    Number of initial chain iterations the sampler treats as burn-in. The chain includes them; discard them before analysis. None for samplers with no burn-in concept (GridSearch, PointEstimateSampler).

Every sampler populates these keys, not only Bayesian ones. Fits driven by a conventional optimizer (CMAES, ScipyMinimize), along with optimization and validation jobs, return an empty dict. So does any job with no metadata blob to read — one that failed before writing one, an unknown job_id, or a job in another organization all surface as a 404, treated here as “no samples” rather than an error.

Parameters:

job_id (str) – The ID of the datafit job whose sample chain to retrieve.

Returns:

A dict with samples, sample_costs, sample_param_names, and sample_burnin keys. Empty if the job recorded no samples.

Return type:

dict[str, Any]

list() → list[JobResponse][source]

List all jobs.

Returns:

List of all jobs with their details.

Return type:

list[JobResponse]

Raises:

ValueError – If the response is not a list or job data format is invalid.

cancel(job_id: str) → JobResponse[source]

Cancel a job.

Parameters:

job_id (str) – The ID of the job to cancel.

Returns:

Updated job details with canceled status.

Return type:

JobResponse

Raises:

ValueError – If the response parsing fails.