Protocols#

Author, save, and convert UCP protocols: write a protocol by hand, parse a vendor cycler file, validate it, save it to a project so simulations and planned measurements can reference it, and export it to a cycler’s native format.

For usage examples and guides, see Managing protocols on docs.ionworks.com.

Protocol client for authoring, saving, and converting UCP protocols.

Provides ProtocolClient for the whole protocol lifecycle: writing a protocol (by hand or by parsing a vendor file), validating it, saving it to a project so simulations and planned measurements can reference it by id, and converting it back out to a vendor-native protocol file (Maccor, Arbin, Neware, BioLogic BT-Test, Novonix).

Saved protocols are stored as experiment_template rows server-side; the SDK calls them protocols throughout.

ionworks.protocol.ConversionTarget#

"arbin" is the .sdu dialect (MITS Pro <=7); "arbin_sdx" is .sdx (MITS Pro 8+). Both are first-class – “arbin” is not deprecated.

alias of Literal[‘maccor’, ‘arbin’, ‘arbin_sdx’, ‘neware’, ‘biologic_bttest’, ‘novonix’]

ionworks.protocol.INCLUDABLE_FIELDS = ('protocol_config', 'parameters_schema', 'time_series_spec', 'metrics_spec', 'plot_options', 'source_protocol')#

Heavy columns omitted from list responses unless named in include.

class ionworks.protocol.ConvertResult(target, primary_filename, primary_bytes, media_type, assets=<factory>)[source]#

Bases: object

Result of converting a UCP to a vendor-native protocol file.

Parameters:
target: str#

The vendor target the protocol was converted for.

primary_filename: str#

Suggested filename for the primary artifact (with extension).

primary_bytes: bytes#

Raw bytes of the primary artifact.

media_type: str#

Media type of the primary artifact.

assets: list[tuple[str, bytes]]#

Side files (e.g. Maccor MWF drive-cycle assets), each as (filename, bytes).

text(encoding='utf-8')[source]#

Decode the primary artifact as text.

Parameters:

encoding (str, optional) – Encoding to decode with. Defaults to utf-8.

Returns:

The decoded primary artifact.

Return type:

str

save(directory)[source]#

Write the primary artifact and any assets to directory.

Parameters:

directory (str or Path) – Target directory. Created if it does not exist.

Returns:

Paths written, primary first followed by assets.

Return type:

list[Path]

__init__(target, primary_filename, primary_bytes, media_type, assets=<factory>)#
Parameters:
Return type:

None

class ionworks.protocol.ProtocolClient(client)[source]#

Bases: object

Client for authoring, saving, and converting protocols.

Covers the full lifecycle:

Saved protocols are project-scoped. Methods that need a project accept project_id; when omitted it falls back to the project_id configured on the parent Ionworks client (resolved from IONWORKS_PROJECT_ID if not passed explicitly), and raise ValueError when no project_id is available from any source.

Parameters:

client (Any)

__init__(client)[source]#

Initialize the ProtocolClient.

Parameters:

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

Return type:

None

list(project_id=None, limit=None, offset=None, *, include=None, name=None, name_exact=None, created_by_email=None, created_after=None, created_before=None, updated_after=None, updated_before=None, order_by=None, order=None)[source]#

List a project’s saved protocols.

The response is lightweight by default: the protocol body and other large columns are omitted and come back as None. Name them in include to fetch them, or call get() for one full protocol.

Filtering, ordering, and pagination are all applied by the database, so total reflects every protocol matching the filters rather than the size of the page returned.

Parameters:
  • project_id (str | None, optional) – Project whose protocols to list. Defaults to the project_id set on the Ionworks client.

  • limit (int | None, optional) – Page size (1-100). When omitted the full list is returned.

  • offset (int | None, optional) – Number of records to skip before the page starts.

  • include (list[str] | None, optional) – Heavy columns to include. Any of INCLUDABLE_FIELDS; unknown names are ignored by the API.

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

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

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

  • created_after (str | None, optional) – ISO datetime bounds on when the protocol was saved.

  • created_before (str | None, optional) – ISO datetime bounds on when the protocol was saved.

  • updated_after (str | None, optional) – ISO datetime bounds on when the protocol was last changed.

  • updated_before (str | None, optional) – ISO datetime bounds on when the protocol was last changed.

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

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

Returns:

The matching protocols, with .count and .total.

Return type:

PaginatedList[Protocol]

get(protocol_id)[source]#

Get a saved protocol by id, including its full body.

Parameters:

protocol_id (str) – Id of the protocol to retrieve.

Returns:

The protocol, with protocol_config and the other heavy columns populated.

Return type:

Protocol

find_by_name(name, project_id=None)[source]#

Find a saved protocol by exact name within a project.

Parameters:
  • name (str) – Exact protocol name to match.

  • project_id (str | None, optional) – Project to search. Defaults to the project_id set on the Ionworks client.

Returns:

The matching protocol (lightweight — call get() for the body), or None when the project has no protocol by that name.

Return type:

Protocol | None

Raises:

ValueError – If more than one protocol in the project has this name. Names are not unique — protocols are deduplicated on their body, so two different protocols may share one — and picking arbitrarily between them would quietly simulate the wrong one. List them with list(name_exact=...) and select by id.

human_readable(protocol_id)[source]#

Render a saved protocol as human-readable text.

Parameters:

protocol_id (str) – Id of the protocol.

Returns:

The protocol described in prose, one line per step.

Return type:

str

source_protocol(protocol_id)[source]#

Return the original protocol text a saved protocol was created from.

Parameters:

protocol_id (str) – Id of the protocol.

Returns:

The source text as originally entered or parsed.

Return type:

str

Raises:

IonworksError – 404 when the protocol has no recorded source text (it was created directly from a UCP dict rather than from source).

create(name, protocol, project_id=None, *, description=None, parameters_schema=None, source_protocol=None, force_create=False)[source]#

Save a protocol to a project.

By default this is content-addressed: saving a protocol whose body already exists in the project returns the existing row rather than a duplicate, so re-running a script is safe. Pass force_create=True to always write a new row — useful for keeping two differently-named copies of the same protocol.

Parameters:
  • name (str) – Name for the protocol.

  • protocol (str or dict) – The protocol as UCP YAML text or an already-parsed dict. A string is sent as source_protocol too unless one is given explicitly, so the original text is preserved.

  • project_id (str | None, optional) – Project to save into. Defaults to the project_id set on the Ionworks client.

  • description (str | None, optional) – Free-text description.

  • parameters_schema (dict | None, optional) – Schema of the parameters the protocol leaves open. Defaults to {} (no open parameters).

  • source_protocol (str | None, optional) – Original protocol text to record. Defaults to protocol when it is a string.

  • force_create (bool, optional) – Write a new row even when an identical protocol already exists. Defaults to False.

Returns:

The saved protocol.

Return type:

Protocol

Raises:

IonworksError – 409 when force_create is set and an identical protocol already exists — the content-hash uniqueness rule cannot be bypassed.

create_or_get(name, protocol, project_id=None, **kwargs)[source]#

Save a protocol, returning the existing one if it is already saved.

Thin alias for create() with force_create=False, named to match the create-or-get helpers on the other sub-clients. Matching is on protocol content, not on name.

Parameters:
  • name (str) – Name for the protocol, used only when creating.

  • protocol (str or dict) – The protocol as UCP YAML text or a parsed dict.

  • project_id (str | None, optional) – Project to save into. Defaults to the client’s project_id.

  • **kwargs (Any) – Passed through to create().

Returns:

The newly saved protocol, or the existing identical one.

Return type:

Protocol

update(protocol_id, *, name=None, description=None)[source]#

Rename a saved protocol or change its description.

Only name and description are editable. A protocol’s body is immutable — saved simulations reference it, so changing it in place would silently rewrite what they ran. Save a new protocol instead.

Parameters:
  • protocol_id (str) – Id of the protocol to update.

  • name (str | None, optional) – New name. Left unchanged when omitted.

  • description (str | None, optional) – New description. Left unchanged when omitted.

Returns:

The updated protocol.

Return type:

Protocol

delete(protocol_id)[source]#

Delete a saved protocol.

Parameters:

protocol_id (str) – Id of the protocol to delete.

Return type:

None

parse_file(file)[source]#

Parse a vendor protocol file into UCP.

Accepts a cycler’s own protocol file (Maccor, Arbin, Neware, Novonix, BioLogic, …) and returns the equivalent UCP. Nothing is saved — pass the result’s ucp to create() to store it.

Parameters:

file (str, Path, or file object) – Path to the protocol file, or an already-open binary file object.

Returns:

The UCP text plus a human-readable rendering and the names of any drive cycles or subroutines the file referenced but did not carry.

Return type:

ParsedProtocol

validate(protocol)[source]#

Validate a UCP protocol string.

Parameters:

protocol (str) – The protocol YAML string to validate.

Returns:

Validation result with valid (bool) and optionally error (str) keys.

Return type:

dict[str, Any]

find_input_references(protocol)[source]#

Find input references (external parameter placeholders) in a protocol.

Parameters:

protocol (str) – The protocol YAML string to inspect.

Returns:

List of input reference names found in the protocol.

Return type:

list[str]

convert(protocol, target, drive_cycles=None, filename_stem='protocol', nominal_capacity_ah=None, verify=False)[source]#

Convert a UCP to a vendor-native protocol file.

Returns the artifact as raw bytes. Use ConvertResult.text() to decode as a string, or ConvertResult.save() to write to disk.

Parameters:
  • protocol (str or dict) – UCP as a YAML string or dict.

  • target (str) – One of maccor, arbin, neware, biologic_bttest, novonix.

  • drive_cycles (dict, optional) – Mapping of drive cycle name → samples, required when the protocol references DriveCycle steps.

  • filename_stem (str, optional) – Stem for the returned primary filename. Defaults to protocol.

  • nominal_capacity_ah (float, optional) – Rated cell capacity in amp-hours. Required for neware when the protocol uses C-rate steps or cutoffs: Neware sets current in absolute mA and has no C-rate mode, so the rate cannot be resolved without it. Other targets express C-rate natively and ignore it.

  • verify (bool, optional) – Ask the server to round-trip the emitted file back through its parser and reject the conversion if the protocol no longer means the same thing – a dropped loop count, goto, or safety bound. Defaults to False, matching the server: the checker still reports several benign artifacts of the Maccor, Arbin and Neware writers as differences, so enabling it can refuse a valid conversion to those targets. Reliable today for biologic_bttest and novonix.

Returns:

Holds the primary artifact bytes plus any side assets.

Return type:

ConvertResult