Cell Measurement

Client for managing cell measurements and time series data uploads.

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

Cell measurement client for managing battery cell test data.

This module provides the CellMeasurementClient for uploading, retrieving, and managing measurement data from battery cell testing. It supports time series data (signed URL upload, redirect-based download), file measurements (signed URL upload, redirect-based download), and properties measurements (direct JSON).

ionworks.api.cell_measurement.PROCESSING_TIMEOUT_SECONDS = 600.0

How long to wait for the server to derive an upload’s steps before giving up. Generous: the work is queued, so it covers both a busy queue and a large file, and giving up only stops the waiting, never the processing.

ionworks.api.cell_measurement.PROCESSING_POLL_SECONDS = 2.0

Seconds between processing_status polls while waiting.

ionworks.api.cell_measurement.ATTACHMENT_POOL_WORKERS = 4

Worker threads used to upload a measurement’s attachments in parallel.

ionworks.api.cell_measurement.ATTACHMENT_MAX_CONCURRENCY = 1

Multipart connections per attachment upload. Parts in flight are ATTACHMENT_POOL_WORKERS x this, and each must beat the storage edge’s timeout.

class ionworks.api.cell_measurement.CellMeasurementClient(client: Any)[source]

Bases: object

Client for managing cell measurement data.

UPLOAD_TIMEOUT: tuple[float, float] = (10, 300)

Timeout for uploads as (connect, read) in seconds. Passed through to the shared transport, so overriding it takes effect on both paths; on the multipart path the read timeout applies per part, not per transfer.

__init__(client: Any) → None[source]

Initialize the CellMeasurementClient.

Parameters:

client (Any) – The HTTP client instance for making API calls.

list(cell_instance_id: str, limit: int | None = None, offset: int | None = None, measurement_type: str | None = None, *, name: str | None = None, name_exact: str | None = None, created_by_email: str | None = None, started_after: str | None = None, started_before: str | None = None, created_after: str | None = None, created_before: str | None = None, updated_after: str | None = None, updated_before: str | None = None, tags_all: Iterable[str] | None = None, tags_any: Iterable[str] | None = None, order_by: str | None = None, order: str | None = None) → PaginatedList[CellMeasurement][source]

List cell measurements for a cell instance with optional filtering.

Always returns a PaginatedList which behaves like a regular list. Use limit and offset to control the page.

Parameters:
  • cell_instance_id (str) – The ID of the cell instance.

  • limit (int | None, optional) – Maximum number of measurements to return per page.

  • offset (int | None, optional) – Number of measurements to skip for pagination.

  • measurement_type (str | None, optional) – Filter by measurement type (e.g. "time_series", "file", "properties"). If None, returns all types.

  • name (str | None, optional) – Case-insensitive substring match on measurement name.

  • name_exact (str | None, optional) – Exact match on measurement name. Takes precedence over name.

  • created_by_email (str | None, optional) – Case-insensitive substring match on the creator’s email.

  • started_after (str | None, optional) – ISO datetime; return measurements started after this time.

  • started_before (str | None, optional) – ISO datetime; return measurements started before this time.

  • created_after (str | None, optional) – ISO datetime; return measurements created after this time.

  • created_before (str | None, optional) – ISO datetime; return measurements created before this time.

  • updated_after (str | None, optional) – ISO datetime; return measurements updated after this time.

  • updated_before (str | None, optional) – ISO datetime; return measurements updated before this time.

  • tags_all (Iterable[str] | None, optional) – Only measurements carrying every one of these tags. Matched case-insensitively.

  • tags_any (Iterable[str] | None, optional) – Only measurements carrying at least one of these tags. Matched case-insensitively.

  • order_by (str | None, optional) – Column to sort by ("name", "created_at", "updated_at", "start_time").

  • order (str | None, optional) – Sort direction: "asc" or "desc".

Returns:

All measurements for the cell instance.

Return type:

PaginatedList[CellMeasurement]

list_by_project(project_id: str, limit: int | None = None, offset: int | None = None, measurement_type: str | None = None, *, q: str | None = None, tags_all: Iterable[str] | None = None, tags_any: Iterable[str] | None = None, order_by: str | None = None, order: str | None = None) → PaginatedList[CellMeasurement][source]

List every cell measurement in a project, across all its cells.

The way to find measurements by tag: list_by_project(project_id, tags_all=["hppc", "25degC"]).

Parameters:
  • project_id (str) – The project to list measurements from.

  • limit (int | None, optional) – Maximum number of measurements to return per page (server default 25, at most 1000).

  • offset (int | None, optional) – Number of measurements to skip for pagination.

  • measurement_type (str | None, optional) – Filter by measurement type ("time_series", "file", "properties").

  • q (str | None, optional) – Free-text search over name, notes, protocol name and tags.

  • tags_all (Iterable[str] | None, optional) – Only measurements carrying every one of these tags. Matched case-insensitively.

  • tags_any (Iterable[str] | None, optional) – Only measurements carrying at least one of these tags. Matched case-insensitively.

  • order_by (str | None, optional) – Column to sort by ("name", "created_at", "updated_at", "start_time").

  • order (str | None, optional) – Sort direction: "asc" or "desc".

Returns:

The page of measurements.

Return type:

PaginatedList[CellMeasurement]

list_tags(project_id: str, q: str | None = None, limit: int | None = None) → PaginatedList[MeasurementTagUsage][source]

List the distinct tags used on a project’s measurements.

Parameters:
  • project_id (str) – The project whose tags to list.

  • q (str | None, optional) – Case-insensitive substring the tag must contain.

  • limit (int | None, optional) – Maximum number of tags to return (server default 50, at most 1000).

Returns:

Tags with the number of measurements carrying each, most used first. total says whether more exist than were returned.

Return type:

PaginatedList[MeasurementTagUsage]

add_tags(measurement_ids: str | Iterable[str], tags: Iterable[str]) → int[source]

Add tags to one or more measurements.

Tags a measurement already has are left alone, so calling this twice is harmless. Each added tag takes the spelling already used in its project.

Parameters:
  • measurement_ids (str | Iterable[str]) – One measurement id or up to 1000 of them.

  • tags (Iterable[str]) – Tags to add.

Returns:

Number of measurements whose tags changed.

Return type:

int

Raises:

IonworksError – NOT_FOUND (404) if a measurement does not exist or is not visible to you; FORBIDDEN (403) if you can read but not update one; BAD_REQUEST (400) if a tag is invalid or a measurement would exceed 50 tags.

remove_tags(measurement_ids: str | Iterable[str], tags: Iterable[str]) → int[source]

Remove tags from one or more measurements, matched case-insensitively.

Parameters:
  • measurement_ids (str | Iterable[str]) – One measurement id or up to 1000 of them.

  • tags (Iterable[str]) – Tags to remove. A tag a measurement does not have is ignored.

Returns:

Number of measurements whose tags changed.

Return type:

int

Raises:

IonworksError – NOT_FOUND (404) or FORBIDDEN (403) as for add_tags().

get(measurement_id: str) → CellMeasurement[source]

Get a specific cell measurement by its ID only.

detail(measurement_id: str, use_cache: bool = True, include_steps: bool = True, include_cycles: bool = True, include_time_series: bool = True) → CellMeasurementDetail[source]

Fetch measurement data.

Automatically adapts to the measurement type:

  • time_series: fetches steps, cycles, and time series data

  • file: fetches signed download URLs for files

  • properties: returns properties from the measurement metadata

Uses flat endpoints with parallel requests and downloads time series and steps via signed URL.

Use the include_* flags to skip fetching data you don’t need, which avoids unnecessary requests. These flags only apply to time_series-type measurements.

Parameters:
  • measurement_id (str) – The ID of the cell measurement.

  • use_cache (bool, optional) – If True (default), check the local file cache before making API calls and store results for future use. Applies to time_series measurements (steps, cycles, and time series data). File URLs are never cached because signed URLs are short-lived.

  • include_steps (bool, optional) – Whether to fetch step data. Defaults to True. Only applies to time_series measurements.

  • include_cycles (bool, optional) – Whether to fetch cycle metrics. Defaults to True. Only applies to time_series measurements.

  • include_time_series (bool, optional) – Whether to fetch time series data. Defaults to True. Only applies to time_series measurements.

Returns:

Measurement details with requested data fields. Fields not requested will be None.

Return type:

CellMeasurementDetail

steps(measurement_id: str, use_cache: bool = True) → DataFrame | DataFrame[source]

Download step data via redirect.

Downloads the raw parquet file directly from storage.

Parameters:
  • measurement_id (str) – The ID of the cell measurement.

  • use_cache (bool, optional) – If True (default), check the local file cache before making an API call and store the result for future use.

Returns:

Step data (polars or pandas based on config).

Return type:

DataFrame

cycles(measurement_id: str, use_cache: bool = True) → DataFrame | DataFrame[source]

Get cycle metrics for a measurement.

Parameters:
  • measurement_id (str) – The ID of the cell measurement.

  • use_cache (bool, optional) – If True (default), check the local file cache before making an API call and store the result for future use.

Returns:

Cycle metrics (polars or pandas based on config).

Return type:

DataFrame

steps_and_cycles(measurement_id: str, use_cache: bool = True) → StepsAndCycles[source]

Get steps and cycles in one call.

More efficient than calling steps() and cycles() separately since cycles are derived from steps on the server.

Parameters:
  • measurement_id (str) – The ID of the cell measurement.

  • use_cache (bool, optional) – If True (default), check the local file cache before making an API call and store the result for future use.

Returns:

Object with steps and cycles DataFrames.

Return type:

StepsAndCycles

time_series(measurement_id: str, use_cache: bool = True, row_range: tuple[int, int] | None = None) → DataFrame | DataFrame[source]

Download time series as a parquet file.

The API endpoint redirects to storage; the HTTP client follows the redirect automatically and returns the raw parquet bytes.

Parameters:
  • measurement_id (str) – The ID of the cell measurement.

  • use_cache (bool, optional) – If True (default), check the local file cache before making an API call and store the result for future use.

  • row_range (tuple[int, int], optional) – Half-open window of absolute row offsets to fetch. Only the row groups holding those rows are transferred, which for a window of a long history is a fraction of the file. Omit for the whole series.

Returns:

The requested rows, or the full time series when row_range is omitted.

Return type:

DataFrame

update(measurement_id: str, data: dict[str, Any]) → CellMeasurement[source]

Update an existing cell measurement.

Parameters:
  • measurement_id (str) – The ID of the cell measurement to update.

  • data (dict[str, Any]) – Dictionary containing the fields to update. This is the path for attaching/detaching a channel_id (pass None to detach), for setting end_time to mark a run complete, and for attaching a protocol_id once the protocol a run executed is known (it must belong to the measurement’s own project). Passing tags replaces the measurement’s tags; use add_tags() / remove_tags() to change some without restating the rest.

Returns:

The updated cell measurement.

Return type:

CellMeasurement

Raises:

IonworksError – When attaching a channel_id breaks a channel rule: BAD_REQUEST (400) for a cross-project channel, a non-time_series measurement, or a missing start_time; CONFLICT (409) for an out-of-commission channel or a time span overlapping another run already on that channel.

delete(measurement_id: str) → None[source]

Delete a cell measurement by measurement ID only.

attach_raw_data(cell_measurement_id: str, raw_data_ids: list[str]) → None[source]

Attach raw-data records to this measurement (bulk, idempotent).

Parameters:
  • cell_measurement_id (str) – The ID of the cell measurement to attach raw data to.

  • raw_data_ids (list[str]) – IDs of the raw-data records to link to this measurement.

detach_raw_data(cell_measurement_id: str, raw_data_id: str) → None[source]

Remove one raw-data link from this measurement.

Parameters:
  • cell_measurement_id (str) – The ID of the cell measurement to detach raw data from.

  • raw_data_id (str) – ID of the raw-data record to unlink from this measurement.

watch(measurement_id: str) → None[source]

Start watching a measurement (the “watch this channel” action).

A watch is per-user and keyed on the measurement, but reads as watching the channel the measurement is running on: it powers the lab “my channels” view (client.lab.watched_channels) and clears itself once the test finishes, so you are no longer watching a channel whose test has ended. Idempotent – watching an already-watched measurement is a no-op.

Parameters:

measurement_id (str) – The ID of the (live) measurement to watch – typically the one on test on a channel (channel.measurement.id in the lab status).

Raises:

IonworksError – NOT_FOUND (404) if the measurement does not exist.

unwatch(measurement_id: str) → None[source]

Stop watching a measurement (the “unwatch this channel” action).

Idempotent – unwatching a measurement you are not watching is a no-op.

Parameters:

measurement_id (str) – The ID of the measurement to stop watching.

list_raw_data(cell_measurement_id: str, limit: int = 100, offset: int = 0) → PaginatedList[RawData][source]

List raw-data records linked to this measurement.

Parameters:
  • cell_measurement_id (str) – The ID of the cell measurement whose raw-data links to list.

  • limit (int, optional) – Maximum number of raw-data records to return per page. Defaults to 100.

  • offset (int, optional) – Number of raw-data records to skip for pagination. Defaults to 0.

Returns:

Raw-data records linked to this measurement.

Return type:

PaginatedList[RawData]

wait_for_processing(measurement_ids: str | Iterable[str], timeout: float = 600.0) → dict[str, dict][source]

Block until the server finishes deriving uploads’ steps.

Polls processing_status until every measurement is terminal. Steps are excluded from the reads, since the server refuses them while processing is in flight.

Pass a whole batch in one call: uploads process concurrently, so the batch takes about as long as its slowest member and shares one timeout. Not fail-fast — every failure is reported once, together, when the batch settles.

Parameters:
  • measurement_ids (str | Iterable[str]) – The measurement, or measurements, to wait on.

  • timeout (float, optional) – Seconds to wait before giving up on whatever is still processing. Shared across the whole batch. Defaults to PROCESSING_TIMEOUT_SECONDS.

Returns:

The last measurement payload read for each id, keyed by id. Returned so a caller that needs the settled row does not have to re-read what the final poll already fetched.

Return type:

dict[str, dict]

Raises:

MeasurementProcessingError – If the server rejected any upload, or if any did not finish within timeout. Inspect failures for the per-measurement reasons. A timeout does not cancel the work — it only stops waiting — so a measurement may still complete afterwards.

create(cell_instance_id: str, measurement_detail: dict[str, Any], validate_strict: bool = False, rated_capacity: float | None = None, voltage_window: tuple[float, float] | None = None, skip_checks: Iterable[str] | None = None, wait_for_processing: bool = True) → CellMeasurementBundleResponse[source]

Create a new cell measurement with steps and time series data.

Uses signed URL upload for better performance with large datasets. Data is uploaded directly to storage as parquet, bypassing backend JSON parsing. No database record is created until the upload is confirmed, preventing orphaned records if upload fails.

Parameters:
  • cell_instance_id (str) – The ID of the cell instance to create the measurement for.

  • measurement_detail (dict[str, Any]) –

    Dictionary containing ‘measurement’, ‘steps’, and ‘time_series’.

    • measurement: dict with ‘name’ (required) and ‘notes’. An optional ‘data_type’ key routes validation: "ocp" for open-circuit potential data and "eis" for impedance spectra (validates the EIS columns and, in strict mode, the Z_Im sign and impedance magnitude). It is a client-side validation hint only and is not persisted. May also carry channel_id (the physical lab channel the test ran on) and start_time. If channel_id is set, this measurement is a channel-linked run, which requires start_time and forbids overlapping another run on the same channel — see the Raises note below and the manage-equipment skill. May also carry tags (a list of free-form labels, normalised as in create_properties()).

    • time_series: pandas DataFrame or dict with time series data

    • steps: optional dict with pre-calculated steps data

  • validate_strict (bool, optional) – If False (default), runs only the always-on checks (positive current convention, time starts at 0, time monotonic, step count sequential, cumulative capacity/energy reset per step). If True, additionally runs: minimum points per step, cycle constant within step, time-gap check (> 5 h), and — when the corresponding inputs are provided — voltage continuity and consecutive-full-step / per-step capacity checks.

  • rated_capacity (float, optional) – Rated (nominal) cell capacity in A.h. Used only when validate_strict=True together with a steps entry in measurement_detail; enables the consecutive same-direction full-step check (hard) and the per-step capacity 500 % soft warning.

  • voltage_window (tuple[float, float], optional) – Rated (V_min, V_max) voltage window of the cell. Used only when validate_strict=True; enables the voltage-continuity check that detects time series rows that are out of chronological order.

  • skip_checks (Iterable[str], optional) – Names of strict-mode checks to skip while keeping validate_strict=True for everything else. Prefer this over disabling strict mode entirely when only a single check is a known false positive for the dataset. See ionworks.api.validators.STRICT_CHECK_NAMES for valid names.

  • wait_for_processing (bool, optional) –

    Block until the server has finished deriving the steps, raising if it could not. Defaults to True, because this call returning is otherwise no evidence the upload was usable: the record is created before the file is parsed, so a file the server cannot read still yields a successful response.

    Pass False when uploading a batch. The server processes uploads concurrently, so submitting all of them and then waiting on every id at once with wait_for_processing() takes about as long as the slowest single upload, where waiting inside each call would take the sum.

Returns:

Response containing the created measurement, steps count, and file path. steps_created is always 0 — steps are derived after the call returns, so the count is not known yet.

Return type:

CellMeasurementBundleResponse

Raises:
  • MeasurementProcessingError – If wait_for_processing and the server could not process the upload, or did not finish in time.

  • MeasurementValidationError – If data validation fails. Non-strict checks cover the sign convention, time axis, step-count monotonicity, and cumulative reset. Strict-only checks additionally cover time gaps, voltage continuity, and consecutive same-direction full steps.

  • IonworksError – When a channel_id in measurement breaks a channel rule: BAD_REQUEST (HTTP 400) if the channel is in another project, the measurement is not time_series, or start_time is missing; CONFLICT (HTTP 409) if the channel is out of commission or the run’s time span overlaps another measurement already on that channel.

extend(measurement_id: str, time_series: Any, wait_for_processing: bool = True) → CellMeasurementBundleResponse[source]

Append a delta time series to an unfinished measurement.

Uploads the delta parquet via signed URL, then confirms so the server stitches it on and recomputes steps. Client-side checks are lighter than create(): empty frame, required columns, and monotonic time only — time need not start at zero.

Stitching runs after confirm returns, so this waits for it by default (see wait_for_processing). A measurement must be done processing and may have only one extend in flight; both refusals are a 409, so retry after waiting rather than treating them as fatal.

Parameters:
  • measurement_id (str) – ID of the unfinished time_series measurement to extend.

  • time_series (Any) – Delta rows as a pandas/polars DataFrame or dict. Must include Time [s] and Step count, be non-empty, and have monotonically non-decreasing time.

  • wait_for_processing (bool, optional) – Block until the server has stitched the delta on, and raise if it could not. Defaults to True. Pass False to return as soon as the work is queued, then wait yourself with wait_for_processing() — note that a failed extend leaves the measurement readable, so it reports as ready and you must check processing_error to see whether the delta actually applied.

Returns:

Updated measurement fields. steps_created is always 0 — steps are recomputed after this call returns, so the count is not known here.

Return type:

CellMeasurementBundleResponse

Raises:
create_or_get(cell_instance_id: str, measurement_detail: dict[str, Any], validate_strict: bool = False, rated_capacity: float | None = None, voltage_window: tuple[float, float] | None = None, skip_checks: Iterable[str] | None = None, wait_for_processing: bool = True) → CellMeasurement[source]

Create a new cell measurement or get existing.

Always returns a CellMeasurement regardless of whether the measurement was newly created or already existed.

Parameters:
  • cell_instance_id (str) – The ID of the cell instance.

  • measurement_detail (dict[str, Any]) – Dictionary containing measurement and time_series (same as create()).

  • validate_strict (bool, optional) – If False (default), skips strict validation. If True, runs strict validation including minimum points per step.

  • rated_capacity (float, optional) – Rated (nominal) cell capacity in A.h. Forwarded to create() to enable the consecutive-full-step and per-step capacity checks.

  • voltage_window (tuple[float, float], optional) – Rated (V_min, V_max) voltage window. Forwarded to create() to enable the voltage-continuity check.

  • skip_checks (Iterable[str], optional) – Names of strict-mode checks to skip. Forwarded to create(). Prefer skipping a specific check over disabling strict mode entirely.

  • wait_for_processing (bool, optional) – Forwarded to create(). Defaults to True. Pass False when uploading a batch and wait on the ids together afterwards with wait_for_processing(). Note that a measurement returned because it already existed has processed long ago, so only the newly created ids are worth waiting on.

Returns:

The measurement (newly created or existing).

Return type:

CellMeasurement

create_properties(cell_instance_id: str, name: str, properties: dict[str, Any], *, notes: str | None = None, protocol: dict[str, Any] | None = None, start_time: str | None = None, end_time: str | None = None, test_setup: dict[str, Any] | None = None, tags: Iterable[str] | None = None) → CellMeasurement[source]

Create a properties-type measurement (no file upload).

Use this for manual measurements like thickness, weight, or capacity that are stored as key-value pairs with units.

Parameters:
  • cell_instance_id (str) – The ID of the parent cell instance.

  • name (str) – Name for the measurement.

  • properties (dict[str, Any]) – Key-value measurements using Quantity format for numerics. Example: {"thickness": {"value": 0.52, "unit": "mm"}}.

  • notes (str | None, optional) – Optional notes for the measurement.

  • protocol (dict[str, Any] | None, optional) – Protocol information.

  • start_time (str | None, optional) – ISO-formatted start time for the measurement.

  • end_time (str | None, optional) – ISO-formatted end time. Set once the test is complete; leave None while it is still running.

  • test_setup (dict[str, Any] | None, optional) – Test setup metadata.

  • tags (Iterable[str] | None, optional) – Free-form labels, e.g. ["baseline", "batch-7"]. Whitespace is trimmed, duplicates are dropped case-insensitively, and a tag already used in the project keeps its existing spelling. At most 50 tags of up to 50 characters each.

Returns:

The created measurement.

Return type:

CellMeasurement

ALLOWED_IMAGE_EXTENSIONS: frozenset[str] = frozenset({'bmp', 'gif', 'jpeg', 'jpg', 'png', 'tiff', 'webp'})

Allowed image file extensions for upload.

create_file(cell_instance_id: str, name: str, filepaths: list[str], *, validate_images: bool = False, notes: str | None = None, protocol: dict[str, Any] | None = None, start_time: str | None = None, end_time: str | None = None, test_setup: dict[str, Any] | None = None, tags: Iterable[str] | None = None) → CellMeasurementBundleResponse[source]

Create a file-type measurement by uploading files.

Uses a three-step signed URL flow: initiate (get signed URLs), upload each file, then confirm (create DB record). Supports any file type (PDFs, numpy arrays, images, etc.).

Set validate_images=True to opt into client-side image validation when uploading image files specifically.

Parameters:
  • cell_instance_id (str) – The ID of the parent cell instance.

  • name (str) – Name for the measurement.

  • filepaths (list[str]) – Local file paths to upload.

  • validate_images (bool, optional) – When True, validate that each file is a real image with an allowed extension before uploading. Defaults to False.

  • notes (str | None, optional) – Optional notes for the measurement.

  • protocol (dict[str, Any] | None, optional) – Protocol information.

  • start_time (str | None, optional) – ISO-formatted start time for the measurement.

  • end_time (str | None, optional) – ISO-formatted end time. Set once the test is complete; leave None while it is still running.

  • test_setup (dict[str, Any] | None, optional) – Test setup metadata.

  • tags (Iterable[str] | None, optional) – Free-form labels, e.g. ["baseline", "batch-7"]. Whitespace is trimmed, duplicates are dropped case-insensitively, and a tag already used in the project keeps its existing spelling. At most 50 tags of up to 50 characters each.

Returns:

Response containing the created measurement and steps_created (0).

Return type:

CellMeasurementBundleResponse

Raises:
  • IonworksError – If validate_images is True and any file is not a valid image, or if upload fails.

  • FileNotFoundError – If any file path does not exist.

list_files(measurement_id: str) → list[str][source]

List filenames in a file-type measurement.

Parameters:

measurement_id (str) – The ID of a file-type cell measurement.

Returns:

Filenames stored in the measurement.

Return type:

list[str]

Raises:

IonworksError – If the measurement is not a file type or does not exist.

download_files(measurement_id: str, use_cache: bool = True, filenames: list[str] | None = None) → dict[str, bytes][source]

Download files for a file-type measurement.

When filenames is provided the list_files round-trip is skipped, which avoids the slow storage-listing endpoint. Use this when you already know the filenames (e.g. from a previous list_files call or from the upload response).

Parameters:
  • measurement_id (str) – The ID of a file-type cell measurement.

  • use_cache (bool, optional) – If True (default), check the local file cache before downloading and store results for future use.

  • filenames (list[str] | None, optional) – Explicit list of filenames to download. When provided, the GET /cell_measurements/{id}/files listing call is skipped.

Returns:

Mapping of filename to file content bytes.

Return type:

dict[str, bytes]

Raises:

IonworksError – If the measurement is not a file type, does not exist, or a download fails.

get_file(measurement_id: str, filename: str) → bytes[source]

Download a single file from a file-type measurement.

This is a convenience wrapper that fetches one file directly without any listing call, making it the fastest way to retrieve a known file.

Parameters:
  • measurement_id (str) – The ID of a file-type cell measurement.

  • filename (str) – Name of the file to download.

Returns:

Raw file content.

Return type:

bytes

Raises:

IonworksError – If the measurement or file does not exist.