Core¶
Core helper mixins used across schema classes.
Schemas for core.
- class ionworks_schema.core.ConfigMixin¶
Bases:
BaseSchemaMixin that automatically captures __init__ parameters for subclasses.
When a class inherits from this mixin, any subclass that defines its own __init__ method will have its parameters automatically captured and stored in self._init_params. This is useful for serialization/deserialization (e.g., to_config methods for reverse parsing).
Additionally, if the __init__ has an “options” parameter, it captures which option keys were explicitly passed in self._options_keys_passed before calling the original __init__.
The captured parameters exclude self and filter out None values.
This mixin also provides config_schema() classmethod that generates a pydantic schema from the class’s __init__ signature. This is used by ionworksschema generation.
Extends:
ionworks_schema.base.BaseSchema- model_config = {'arbitrary_types_allowed': True, 'extra': 'forbid', 'populate_by_name': True, 'validate_assignment': True, 'validate_by_alias': True, 'validate_by_name': True}¶
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
Containers¶
BaseSchema and the pipeline containers every element is assembled into.
Base classes for ionworks_schema.
- ionworks_schema.base.reject_runtime_object(value: Any, field_name: str, expected: str) NoReturn¶
Reject a value that is neither a config dict nor a schema instance.
Centralizes the boundary guard shared by the distribution, sampler, prior, and objective resolvers. The schema contract holds only
ionworks_schemaobjects — a config dict or the matching schema instance — so a live runtime object must be converted (via.to_config()or the matchingiwsschema class) before it enters a schema, rather than embedded raw. Callers invoke this on the fall-through branch after they have already accepted the dict and schema-instance forms.Parameters¶
- valueAny
The rejected value, echoed into the error message via
repr.- field_namestr
The schema field being resolved (e.g.
"distribution","sampler","prior","objective"), used to phrase the message.- expectedstr
User-facing description of the accepted non-dict form, phrased with its article so it reads in the message (e.g.
"a Distribution instance","an ionworks_schema objective instance"). Use the public vocabulary, not an internal implementation class name.
Raises¶
- ValueError
Always. The function never returns normally.
- class ionworks_schema.base.BaseSchema¶
Bases:
BaseModelShared parent of every schema class in this package.
You won’t usually construct
BaseSchemadirectly — you’ll construct one of its concrete subclasses (iws.Pipeline,iws.DataFit,iws.Parameter, …). It provides the.to_config()method every schema uses to produce the dict you submit throughionworks-api, and it rejects unknown fields so typos are caught at construction time instead of silently lost on the way to the server..to_config()is the only supported serializer. Pydantic’s own.model_dump()is not a wire format — it omits thetypediscriminator and emits Python attribute names rather than the wire names the API expects (data_inputrather thandata). Always use.to_config()to build a payload.Extends:
pydantic.main.BaseModel- model_config = {'arbitrary_types_allowed': True, 'extra': 'forbid', 'populate_by_name': True, 'validate_assignment': True, 'validate_by_alias': True, 'validate_by_name': True}¶
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- to_config() dict¶
Build the dict you submit through
ionworks-api.This is the bridge between the friendly schema objects you construct in Python (
iws.DataFit(...),iws.Normal(...), …) and the JSON-shaped payload the Ionworks API expects when you submit a job. Build your schema, call.to_config(), and pass the result to the API client.Nested schemas are converted recursively,
Nonefields are dropped so the payload stays minimal, and a"type"key identifying the concrete class is appended for every component that needs to be re-identified at the server.Notes¶
This is the only supported serializer. Do not use Pydantic’s
.model_dump()to build an API payload: it is not a wire format..model_dump()omits the"type"discriminator and emits Python attribute names rather than the wire names the API expects (data_inputrather thandata), so it produces a different dict than.to_config()— one the API may reject. Passingby_alias=Truerecovers the wire names but not the discriminator, so it is still not a payload. For example,iws.stats.Uniform(lb=0.0, ub=1.0).to_config()yields{"distribution": "Uniform", "lb": 0.0, "ub": 1.0}(carrying the discriminator) whereas.model_dump(exclude_none=True)yields just{"lb": 0.0, "ub": 1.0}.
- run(*args, **kwargs)¶
- class ionworks_schema.base.Pipeline(elements: dict | None = None, output_file: str | None = None, name: str | None = None, description: str | None = None)¶
Bases:
BaseSchemaA sequence of steps that together produce a parameterised cell model.
Each step (an “element”) does one of: pull parameters from a source (
DirectEntry), fit parameters to measured data (DataFit), compute derived quantities (Calculation), or check the fitted parameters against held-out data (Validation). The parameters produced by one element are passed on to the next, so the order matters.Once you’ve added every element you need, call
.to_config()on the pipeline and submit the result throughionworks-apito run the whole job server-side.Parameters¶
- elementsdict, optional
Mapping of element name to pipeline element (
DataFit,DirectEntry,Validation,Calculation, …). The name is used to identify the element in the pipeline report.Noneis treated as an empty pipeline byto_config.- output_filestr, optional
Optional file path for persisting the final parameter values produced by the pipeline. If
None, parameters are not written to disk.- namestr, optional
Human-readable name for the pipeline, used in reports and logs.
- descriptionstr, optional
Free-text description of what the pipeline does.
Examples¶
>>> # known parameters (e.g. ambient temperature) >>> known = iws.direct_entries.DirectEntry( ... parameters={"Ambient temperature [K]": 298.15}, ... ) >>> # fit one parameter against an OCP measurement >>> obj = iws.objectives.OCPHalfCell( ... electrode="positive", ... data_input="path/to/ocp.csv", ... ) >>> fit = iws.DataFit( ... objectives={"ocp": obj}, ... parameters={"Positive electrode capacity [A.h]": iws.Parameter( ... "Positive electrode capacity [A.h]", initial_value=3.0, bounds=(2.0, 4.0), ... )}, ... ) >>> # validate the fit against held-out cycling data >>> val_obj = iws.objectives.CurrentDriven( ... data_input="path/to/cycle.csv", options={"model": "SPM"} ... ) >>> val = iws.Validation(objectives={"cycle": val_obj}) >>> pipeline = iws.Pipeline({"known": known, "ocp fit": fit, "validate": val}) >>> config = pipeline.to_config() >>> # then submit `config` via ionworks-api
Extends:
ionworks_schema.base.BaseSchema- to_config() dict¶
Build the pipeline payload you submit through
ionworks-api.Walks every element you added to
elements, serialises it (each element’s ownto_config), and tags it with its kind ("entry","data_fit","validation", …) so the server knows how to dispatch it. Pass the returned dict to the Ionworks API to run the full pipeline.
- model_config = {'arbitrary_types_allowed': True, 'extra': 'forbid', 'populate_by_name': True, 'validate_assignment': True, 'validate_by_alias': True, 'validate_by_name': True}¶
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- class ionworks_schema.base.SimplePipeline(elements: dict | None = None, output_file: str | None = None, name: str | None = None, description: str | None = None)¶
Bases:
PipelineA pipeline that permits at most one expensive element.
SimplePipelineis identical toPipelineexcept that it rejects configurations containing more than one expensive element (DataFit,ArrayDataFit, orValidation) at construction time. Use it when you intend to submit via the SimplePipeline API endpoint, which enforces the same constraint server-side.Parameters¶
- elementsdict, optional
Mapping of element name to pipeline element (
DataFit,DirectEntry,Validation,Calculation, …). At most one element may be aDataFit,ArrayDataFit, orValidation.- output_filestr, optional
Optional file path for persisting the final parameter values produced by the pipeline. If
None, parameters are not written to disk.- namestr, optional
Human-readable name for the pipeline, used in reports and logs.
- descriptionstr, optional
Free-text description of what the pipeline does.
Raises¶
- ValueError
If
elementscontains more than oneDataFit,ArrayDataFit, orValidationelement.
Examples¶
>>> entry = iws.direct_entries.DirectEntry( ... parameters={"Ambient temperature [K]": 298.15}, ... ) >>> obj = iws.objectives.OCPHalfCell( ... electrode="positive", ... data_input="path/to/ocp.csv", ... ) >>> fit = iws.DataFit( ... objectives={"ocp": obj}, ... parameters={"Positive electrode capacity [A.h]": iws.Parameter( ... "Positive electrode capacity [A.h]", ... initial_value=3.0, ... bounds=(2.0, 4.0), ... )}, ... ) >>> pipeline = iws.SimplePipeline( ... elements={"known": entry, "ocp fit": fit}, ... name="Single OCP fit", ... ) >>> config = pipeline.to_config()
Extends:
ionworks_schema.base.Pipeline- model_config = {'arbitrary_types_allowed': True, 'extra': 'forbid', 'populate_by_name': True, 'validate_assignment': True, 'validate_by_alias': True, 'validate_by_name': True}¶
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].