koios-model-utils
Annotate ONNX models with the metadata the Koios IoT platform needs to run them.
This library is the canonical writer (and reader) of the koios.training
and koios.bindings metadata_props blocks Koios consumes when a model
is uploaded to its predict engine. Bring your own ONNX file from any
framework (Stable-Baselines3, PyTorch, TensorFlow/Keras, scikit-learn);
the library only touches metadata.
The wire format is fully documented in docs/CONTRACT.md.
Installation
pip install koios-model-utils
Only runtime dependency is onnx>=1.14. No torch, no SB3, no CLI —
this is a metadata library.
Quick start
import onnx
from koios_model_utils import (
Algorithm,
InputBinding,
NormalizationSource,
NormalizationType,
OutputBinding,
TrainingMeta,
embed_koios_metadata,
)
model = onnx.load("my_model.onnx")
embed_koios_metadata(
model,
inputs=[
InputBinding(name="tank_temperature", description="Tank temperature (C)"),
InputBinding(name="pressure", description="Vessel pressure (kPa)"),
],
outputs=[
OutputBinding(
name="valve_position",
range_min=0.0,
range_max=100.0,
normalization_type=NormalizationType.SYMMETRIC,
normalization_source=NormalizationSource.CUSTOM,
custom_minimum=0.0,
custom_maximum=100.0,
clamp_output=True,
),
],
training=TrainingMeta(
scenario_name="tank_temperature",
algorithm=Algorithm.PPO,
obs_depth=5,
sample_rate=1.0,
),
)
onnx.save(model, "my_model_koios.onnx")
The Koios webapp reads both metadata blocks on upload and uses them to
configure model.sample_rate, the input/output bindings, normalization
rules, and (for DRL classifiers) the action map.
See examples/ for runnable scripts.
Reading metadata back
The mirror of embed_koios_metadata:
from koios_model_utils import parse_koios_metadata
parsed = parse_koios_metadata(onnx.load("my_model_koios.onnx"))
print(parsed.training) # TrainingMeta dataclass (or None)
print(parsed.inputs) # list[InputBinding]
print(parsed.outputs) # list[OutputBinding]
print(parsed.has_metadata) # True if any koios.* prop was present
If the JSON has already been pulled out of the ONNX file (e.g. persisted
in a database column), use parse_koios_metadata_from_dict and pass
{"koios.training": {...}, "koios.bindings": {...}} directly.
Public API
Dataclasses
| Class | Purpose |
|---|---|
InputBinding |
One observation feature — name, normalization rules, failure bounds |
OutputBinding |
One action / output — name, range, normalization, clamping |
TrainingMeta |
Model-level metadata — algorithm, sample/scan rate, model type, action map |
ActionMapEntry |
One row of a DISCRETE-mode action map (value + label) |
ParsedKoiosMetadata |
Return type of parse_koios_metadata |
All dataclasses run their validators in __post_init__, so bad
combinations (e.g. Z_SCORE + custom_minimum) raise at construction.
Enums
NormalizationType, NormalizationSource, ModelType, OutputMode,
Algorithm, FailureRangeMode — all enum.StrEnum, all uppercase wire
values. See enums.py for the members.
Pass enum members rather than raw strings — the dataclasses accept either, but enums catch typos at type-check time.
Functions
| Function | Purpose |
|---|---|
embed_koios_metadata(model, *, inputs, outputs, training=None, output_denormalized=False) |
Write koios.training + koios.bindings into an ONNX model (in-place) |
parse_koios_metadata(model) |
Parse them back into typed dataclasses |
parse_koios_metadata_from_dict(raw) |
Same, but from an already-decoded dict |
Errors
KoiosMetadataError, UnsupportedSchemaVersionError,
KoiosMetadataDecodeError — all ValueError subclasses raised by the
parser.
sample_rate vs scan_rate
sample_rate is the interval (seconds) the model was trained at.
The Koios predict engine resamples historical inputs to this rate.
scan_rate is how often the predict engine executes the model. When
omitted (the common case), it inherits sample_rate — forecasting
models train and run at the same cadence. Set it explicitly for RL
controllers that need to act faster than the simulator step they were
trained against (e.g. sample_rate=1.0 history lookback, scan_rate=0.1
control loop).
Discrete (classification / DQN) heads
For models that emit an action index instead of a continuous value, set
output_mode and pass an action_map:
from koios_model_utils import (
ActionMapEntry, OutputMode, TrainingMeta,
)
training = TrainingMeta(
algorithm="DQN",
output_mode=OutputMode.DISCRETE,
action_map=[
ActionMapEntry(value=-1.0, label="Decrease setpoint"),
ActionMapEntry(value=0.0, label="Hold"),
ActionMapEntry(value=1.0, label="Increase setpoint"),
],
)
action_map also accepts raw {"value": ..., "label": ...} dicts and
coerces them to ActionMapEntry at construction — extra keys are
dropped, missing keys raise.
Contract & versioning
The wire format is at schema_version 1. docs/CONTRACT.md
is the source of truth for every field, every default, and every
server-side policy applied on upload.
The library and the Koios webapp move in lockstep: any wire-format change here requires a coordinated webapp release. The CONTRACT lays out exactly which keys the webapp reads, the forward-compat rules within v1, and when a v2 bump would be needed.
Development
pip install -e ".[dev]"
make test
make lint
License
Apache License 2.0 — see LICENSE.
Metadata
Release files for koios-model-utils 1.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| koios_model_utils-1.2.0.tar.gz | 49.9 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| koios_model_utils-1.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 74.4 kB
Release files / koios_model_utils-1.2.0.tar.gz
| Download URL | koios_model_utils-1.2.0.tar.gz |
|---|---|
| Size | 49.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
91c93d0ee365c5bed76cb1938a57f5d2be4f131ff2b919925ac657ec1fbd7140
|
|
BLAKE2b-256 checksum How to use checksums |
457cef629808468c9a18eac4f273d09bae681705bc39421b3977554c3382d2a7
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 30, 2026.
Transparency logRelease files / koios_model_utils-1.2.0-py3-none-any.whl
| Download URL | koios_model_utils-1.2.0-py3-none-any.whl |
|---|---|
| Size | 24.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
b34afd94aa0ab3cdd2bbca59a836349b6c49779e65fabc270c2e72dde7e870cc
|
|
BLAKE2b-256 checksum How to use checksums |
be2d32c508529ba493fd67e8d6ea8aa2d0d6685727c605fe8e6a478e1cacdf31
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 30, 2026.
Transparency log