Client#
The main entry point for interacting with the Ionworks API.
Main client module for the Ionworks API.
This module provides the Ionworks client, which is the main entry point
for interacting with the Ionworks API. It handles authentication, request/response
processing, and provides access to all API resources through sub-clients.
- class ionworks.client.Ionworks(api_key=None, api_url=None, project_id=None, dataframe_backend=None, timeout=None, max_retries=None, token=None, organization_id=None)[source]#
Bases:
objectClient for interacting with the Ionworks API.
Handles authentication, request/response processing, and provides access to all API resources through sub-clients.
- Parameters:
- __init__(api_key=None, api_url=None, project_id=None, dataframe_backend=None, timeout=None, max_retries=None, token=None, organization_id=None)[source]#
Initialize Ionworks client.
Authentication uses either a bearer token or an API key. If a token is provided (argument or
IONWORKS_API_TOKENenv var) it is sent as anAuthorization: Bearerheader; otherwise an API key (argument orIONWORKS_API_KEYenv var) is sent as anX-API-Keyheader. A token takes precedence when both are present.- Parameters:
api_key (str | None) – API key. If not provided, will look for IONWORKS_API_KEY env var.
api_url (str | None) – API URL. If not provided, will look for IONWORKS_API_URL env var.
project_id (str | None) – Default project ID to use for sub-client methods that take a
project_idargument. If not provided, will look for theIONWORKS_PROJECT_IDenv var (falling back to the deprecatedPROJECT_IDenv var with aDeprecationWarning). May be left unset; methods that need a project will raise a clear error if none is available.dataframe_backend (str | None) – DataFrame backend for returned data: “polars” or “pandas”. If not provided, uses IONWORKS_DATAFRAME_BACKEND env var (defaults to “polars”).
timeout (int | None) – Request timeout in seconds. Defaults to 10 seconds if not provided.
max_retries (int | None) – Maximum number of retries for failed requests. Defaults to 5 if not provided. Retries occur on connection errors, timeouts, and 5xx server errors.
token (str | None) – Bearer token to authenticate with instead of an API key. Sent as an
Authorization: Bearerheader. Falls back to theIONWORKS_API_TOKENenv var, but only when neithertokennorapi_keyis passed explicitly: an argument always outranks the environment, and a token outranks an API key only within the same source. SoIonworks(api_key=...)authenticates with that key even in a shell (or an agent tool subprocess) that exportsIONWORKS_API_TOKEN.organization_id (str | None) – Organization to scope every request to, sent as an
X-Organization-Idheader. Falls back to theIONWORKS_ORGANIZATION_IDenv var. Relevant when the auth principal spans multiple organizations (a bearer token usually does); with an API key the organization is already fixed by the key and this can be left unset. When unset entirely, no header is sent and the backend resolves the organization from the credential.
- Return type:
None
- request(method, endpoint, json_payload=None)[source]#
Make a request to the Ionworks API with standardized error handling.
Requests use the configured timeout and will retry up to the configured maximum number of times on connection errors, timeouts, and 5xx server errors.
- request_raw(method, endpoint, timeout=None)[source]#
Make a request and return raw response bytes.
Intended for endpoints that return binary data or redirect to storage. Uses the session (which follows redirects automatically), so auth headers are sent on the initial request and stripped on cross-origin redirects.
- post_multipart(endpoint, files=None, params=None)[source]#
POST to
endpointwith optional multipart files and query params.When
filesisNoneor empty, the request is sent as a plain POST with only query-string params (no body, no multipartContent-Type).- Parameters:
endpoint (str) – API endpoint path.
files (dict[str, Any] or None, optional) – Files mapping in the form expected by
requests(e.g.{"file": (filename, fileobj, content_type)}). PassNonefor endpoints that take only query-string params.params (dict[str, Any] | None, optional) – Query string parameters.
- Returns:
Parsed JSON response body.
- Return type:
Any
- delete(endpoint)[source]#
Make a DELETE request using the request helper.
- Parameters:
endpoint (str)
- Return type:
None
- upload_multipart(endpoint, *, data=None, files=None, method='POST')[source]#
Send a
multipart/form-datarequest.Goes through the session (not bare
requests.post) so the upload gets the retry-aware adapter.requestsbuilds theContent-Typeheader (with the right boundary) only when none is supplied, so the session’s JSONContent-Typeis dropped for this request viaheaders={"Content-Type": None}.- Parameters:
endpoint (str) – API endpoint path, e.g.
"/models/upload-custom".data (dict[str, Any] | None) – Form fields to send alongside the file(s).
files (dict[str, Any] | None) –
requests-stylefilesmapping (typically{"file": (filename, fileobj, content_type)}).method (str, optional) – HTTP method to use. Defaults to
"POST"for create-style endpoints; pass"PATCH"for endpoints that replace an existing resource’s file.
- Returns:
Parsed JSON response, or the raw
Responseif the response body isn’t JSON.- Return type:
Any
- whoami()[source]#
Return the user profile the configured API key resolves to.
Hits
GET /users/meand is the recommended way to debug API-key issues: theauthorized_organizationfield is the organization this request is authorized as — for SDK requests, that’s the org the configured API key was issued for, which is the source of truth for permission checks on every call the SDK makes. Theorganizationsfield is the user’s full membership list and is a different question.- Returns:
User profile payload. Notable keys:
id: user idemail: user emailauthorized_organization:{"id": ..., "name": ...}orNone— the org this request is authorized as. For SDK requests, the org the API key is scoped to.organizations: list of every org the user belongs to.
- Return type:
- Raises:
IonworksError –
status_code=401if the configured API key is missing, wrong, or expired.
Examples
>>> me = client.whoami() >>> me["authorized_organization"] {'id': '...', 'name': 'Acme Battery'}
- resolve_measurement(cell_specification, cell_instance, measurement, *, project_id=None)[source]#
Resolve a measurement from human-readable names.
Walks the spec -> instance -> measurement hierarchy by name, filtering each level server-side via
name_exact, and returns the resolved measurement. Saves callers from hand-walking the three list endpoints.- Parameters:
cell_specification (str) – Exact name of the cell specification.
cell_instance (str) – Exact name of the cell instance within that specification.
measurement (str) – Exact name of the measurement within that instance.
project_id (str | None, optional) – Project to resolve the specification within. Defaults to the client’s project. Spec names are unique per project, not per organization, so resolving without a project would report a name shared with a sibling project as ambiguous.
- Returns:
The resolved measurement (use
.idfor the measurement id).- Return type:
- Raises:
IonworksError –
status_code=404if any level has no match, or409if a name is ambiguous within its parent.ValueError – If no
project_idis given and the client has no default.
Examples
>>> m = client.resolve_measurement("Cell A spec", "Cell A #1", "RPT 0") >>> m.id '...'
- capabilities()[source]#
Fetch platform capabilities and domain context.
Returns domain knowledge (battery data hierarchy, key concepts), authentication info, and pointers to JSON Schema endpoints.
- schema(name)[source]#
Fetch a discovery schema by name.
- Parameters:
name (str) –
Schema to fetch. Supported values:
"data"— cell data hierarchy (specifications, instances, measurements, steps, time_series)."protocol"— Universal Cycler Protocol (UCP) JSON Schema.
- Returns:
The requested schema.
- Return type:
- Raises:
ValueError – If name is not a recognised schema.
- pybamm_models()[source]#
List pybamm/ionworks model classes and option values.
Use this to decide whether you can express your model as a config (
client.model.create({"config": {"pybamm_model": ..., "options": {...}}})) or whether you needclient.model.upload_customfor a custompybamm.BaseModelsubclass.
- validate_pybamm_model_config(pybamm_model, options=None, module='lithium_ion')[source]#
Check whether a (model, options) combination is buildable.
Tries to instantiate the model server-side via the same code path the simulation pipeline uses. Returns
{"valid": True}on success, or{"valid": False, "error": <message>, "error_type": <exception class>}if pybamm/ionworks rejects the combination. Nothing is persisted.- Parameters:
pybamm_model (str) – Class name (e.g.
"DFN","SPM","ECM"). One of the names listed bypybamm_models().options (dict[str, Any] | None, optional) – Options dict passed to the model constructor.
module (str, optional) – PyBaMM submodule (
"lithium_ion"or"lead_acid"). Ignored for ionworks-specific models. Defaults to"lithium_ion".
- Returns:
Validation result.
- Return type: