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.api.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.api.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.api.protocol.ConvertResult(target: str, primary_filename: str, primary_bytes: bytes, media_type: str, assets: list[tuple[str, bytes]]=<factory>)[source]¶
Bases:
objectResult of converting a UCP to a vendor-native protocol file.
- assets: list[tuple[str, bytes]]¶
Side files (e.g. Maccor MWF drive-cycle assets), each as
(filename, bytes).
- class ionworks.api.protocol.ProtocolClient(client: Any)[source]¶
Bases:
objectClient for authoring, saving, and converting protocols.
Write UCP or
parse_file()a vendor file; check it withvalidate()andfind_input_references(); store it withcreate()orcreate_or_get()and pass its id to a simulation or planned measurement;convert()exports a vendor-native file. Saved protocols are project-scoped:project_iddefaults to the client’s (IONWORKS_PROJECT_ID), and with neither, methods raiseValueError.- __init__(client: Any) None[source]¶
Initialize the ProtocolClient.
- Parameters:
client (Any) – The HTTP client instance for making API requests.
- list(project_id: str | None = None, limit: int | None = None, offset: int | None = None, *, include: list[str] | None = None, protocol_group_id: str | None = None, name: str | None = None, name_exact: str | None = None, created_by_email: str | None = None, created_after: str | None = None, created_before: str | None = None, updated_after: str | None = None, updated_before: str | None = None, order_by: str | None = None, order: str | None = None) PaginatedList[Protocol][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.protocol_group_id (str | None, optional) – Only protocols assigned to this group. Omit to include all groups.
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: str, project_id: str | None = None) Protocol | 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: str) str[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: str, protocol: str | dict, project_id: str | None = None, *, description: str | None = None, parameters_schema: dict[str, Any] | None = None, source_protocol: str | None = None, force_create: bool = False, protocol_group_id: str | None = None) Protocol[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.protocol_group_id (str | None, optional) – Group in the same project to assign this protocol to. When content already exists, supplying a group also assigns the existing row.
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: str, protocol: str | dict, project_id: str | None = None, **kwargs: Any) Protocol[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: str, *, name: str | None = None, description: str | None = None, protocol_group_id: str | None | Unset = Unset.TOKEN) Protocol[source]¶
Rename, describe, or group a saved protocol.
name,description, and group membership 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.
protocol_group_id (str | None | Unset, optional) – Omit to preserve membership; pass a group id to assign, or
Noneto remove the protocol from its group.
- Returns:
The updated protocol.
- Return type:
- delete(protocol_id: str) None[source]¶
Delete a saved protocol.
- Parameters:
protocol_id (str) – Id of the protocol to delete.
- parse_file(file: str | Path | IO[bytes]) ParsedProtocol[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: str) list[str][source]¶
Find input references (external parameter placeholders) in a protocol.
- convert(protocol: str | dict, target: Literal['maccor', 'arbin', 'arbin_sdx', 'neware', 'biologic_bttest', 'novonix'], drive_cycles: dict[str, Any] | None = None, filename_stem: str = 'protocol', nominal_capacity_ah: float | None = None, verify: bool = False) ConvertResult[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
newareandbiologic_bttestwhen the protocol uses C-rate steps or cutoffs: both export them as absolute currents, 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:
Protocol groups¶
Use client.protocol_group to create, list, rename, and delete project-scoped
families. Assign protocols on create/update and filter their list by group:
group = client.protocol_group.create("Schedule family")
protocol = client.protocol.create(
"Simulation r1", protocol_yaml, protocol_group_id=group.id
)
members = client.protocol.list(protocol_group_id=group.id)
client.protocol.update(protocol.id, protocol_group_id=None) # ungroup
Omitting protocol_group_id on update preserves membership. Deleting a group
ungroups its protocols without deleting them. Inline simulation submissions do
not inherit membership automatically; assign the saved protocol after the run.
Manage project-scoped families of related protocols.
- class ionworks.api.protocol_group.ProtocolGroupClient(client: Any)[source]¶
Bases:
objectManage groups; assign members with
client.protocol.create/update.Groups belong to one project and have unique names within that project. They organize protocols without changing their immutable bodies or ids.
- list(project_id: str | None = None, limit: int | None = None, offset: int | None = None, *, name: str | None = None, created_by_email: str | None = None, created_after: str | None = None, created_before: str | None = None, updated_after: str | None = None, updated_before: str | None = None, order_by: str | None = None, order: str | None = None) PaginatedList[ProtocolGroup][source]¶
List groups with member counts, pagination, and server-side filters.
project_iddefaults to the client’s project.nameandcreated_by_emailare case-insensitive substring filters. Date bounds are ISO datetimes; order by name, created_at, or updated_at.
- get(group_id: str) ProtocolGroup[source]¶
Fetch a group by id.
- create(name: str, project_id: str | None = None, *, description: str | None = None) ProtocolGroup[source]¶
Create a group; an existing name in this project raises a conflict.
Search existing groups before creating a family for debugging variants.
project_iddefaults to the client’s project.