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:
objectResult of converting a UCP to a vendor-native protocol file.
- Parameters:
- assets: list[tuple[str, bytes]]#
Side files (e.g. Maccor MWF drive-cycle assets), each as
(filename, bytes).
- class ionworks.protocol.ProtocolClient(client)[source]#
Bases:
objectClient for authoring, saving, and converting protocols.
Covers the full lifecycle:
author — write UCP by hand, or
parse_file()a vendor protocol filecheck —
validate(),find_input_references()save —
create()(orcreate_or_get()) stores the protocol in a project;list(),get(),update(),delete()manage saved onesuse — pass the saved id to a simulation or a planned measurement
export —
convert()emits a vendor-native protocol file
Saved protocols are project-scoped. Methods that need a project accept
project_id; when omitted it falls back to theproject_idconfigured on the parentIonworksclient (resolved fromIONWORKS_PROJECT_IDif not passed explicitly), and raiseValueErrorwhen 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 inincludeto fetch them, or callget()for one full protocol.Filtering, ordering, and pagination are all applied by the database, so
totalreflects 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, orupdated_at.order (str | None, optional) – Sort direction,
"asc"or"desc".
- Returns:
The matching protocols, with
.countand.total.- Return type:
- find_by_name(name, project_id=None)[source]#
Find a saved protocol by exact name within a project.
- Parameters:
- Returns:
The matching protocol (lightweight — call
get()for the body), orNonewhen 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.
- 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:
- 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=Trueto 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_protocoltoo 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
protocolwhen 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:
- Raises:
IonworksError – 409 when
force_createis 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()withforce_create=False, named to match the create-or-get helpers on the other sub-clients. Matching is on protocol content, not onname.- Parameters:
- Returns:
The newly saved protocol, or the existing identical one.
- Return type:
- update(protocol_id, *, name=None, description=None)[source]#
Rename a saved protocol or change its description.
Only
nameanddescriptionare 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.
- 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
ucptocreate()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:
- find_input_references(protocol)[source]#
Find input references (external parameter placeholders) in a protocol.
- 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, orConvertResult.save()to write to disk.- Parameters:
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
newarewhen 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_bttestandnovonix.
- Returns:
Holds the primary artifact bytes plus any side assets.
- Return type: