@casadi/casadi-reader
Read CasADi serialization into typed fields, values, containers and shared references, without installing CasADi or loading its plugins.
The reader does not interpret SX/MX instructions, name mathematical operations, reconstruct entry mappings, or build visualization graphs. Those tasks belong in casadi-viz. An ONNX-backed function is read as serialized configuration and model bytes; the reader never runs ONNX.
JavaScript, Python, C, C++, MATLAB and Julia expose the same structural document contract. Each implementation is native to its language and generated by the same Python tool. CI builds and tests packages for all six languages.
Development happens on generate.
CI generates and tests all six readers, then commits the complete, reproducible
snapshot to main. Generated source is committed on main, not on generate.
generation.json identifies the source commit. Release workflows and ZIP
packaging are maintained on generate and included in the generated snapshot.
API
import {decode, open} from '@casadi/casadi-reader';
const document = decode(serializedText);
const fromFile = await open(file, {lazy: true}); // browser File/Blob
const root = document.objects[document.root];
console.log(root.type, root.fields);
decode() accepts encoded .casadi text. open() accepts a File/Blob.
decodeCasadi remains an alias for decode; both return structural documents.
The output is ordinary JavaScript data:
{
format: 'casadi_serialization',
version: 1,
serializationProtocol: 3,
root: 8,
roots: [{$ref: 8}],
objects: [
// ... shared objects ...
{
type: 'Function',
fields: [
{name: 'Function::null', type: 'bool', value: false},
// Serialized field order and duplicate field names are preserved.
],
layouts: ['MXFunction::serialize_body', /* base layouts ... */]
}
]
}
The example's indices are illustrative. $ref values are
zero-based indices into objects. Shared definitions appear once, even when
referenced by several functions. Inline structures have their own type and
fields. Vectors are arrays, pairs are two-element arrays, and maps are
{$map: [[key, value], ...]} so arbitrary key types and field order survive.
Repeated serializer fields remain repeated entries, not overwritten properties.
64-bit integers outside JavaScript's exact range use {$integer: "..."};
nonfinite floating-point values use {$float: "..."}. Records and fields contain no source byte ranges.
A file can contain several roots; roots retains them in order. root is a
convenience index for a single shared-object root, otherwise null.
Lazy bytes
const document = await open(resourceFile, {type: 'Resource', lazy: true});
const root = document.objects[document.root];
const blob = root.fields.find(f => f.name === 'ZipMemResource::blob').value;
const firstBytes = await blob.read(0, 64);
type selects a raw SerializingStream root instead of FileSerializer framing.
Resource streams use the same archive representation embedded inside FMUs;
complete saved FMU functions are not yet a validated layout family.
Lazy byte handles expose offset, byteLength and read(offset, length).
Text-input reads are synchronous; File/Blob reads are asynchronous. JSON output
contains a small descriptor and requires the original source to retrieve bytes.
Opaque streams are deferred in lazy mode. Large serialized strings are also
deferred (default lazyThreshold: 65536 bytes). Smaller strings are decoded as
UTF-8 where possible; other strings retain their bytes as {$bytes: [...]} in
eager mode or a lazy byte handle in lazy mode. No archive extraction occurs.
Lazy File/Blob opening loads metadata pages and skips payload pages by their declared lengths. It requires unpadded encoded files, as emitted by CasADi. Text input accepts surrounding whitespace but necessarily retains the supplied encoded string. Graph fields and containers are currently eager; lazy mode specifically concerns opaque byte payloads.
Browser and CLI
Published packages contain bundled browser ESM with generated reading functions.
They do not fetch or parse the source scheme JSON at runtime. A browser can
import a pinned https://unpkg.com/@casadi/casadi-reader@VERSION/dist/index.js
from a module script without a bundler or an import map.
npx @casadi/casadi-reader model.casadi model.json
# Or, for a raw Resource stream:
npx @casadi/casadi-reader --type Resource --lazy resource.casadi
There are no runtime dependencies. Building the npm package needs Node 22+, Python 3.9+ and the development dependencies in package-lock.json.
Scheme and coverage
CasADi's misc/generate_serialization_scheme.py produces the vendored
schemes/serialization_scheme.json: decoding rules and validation metadata,
without source bodies, pack expressions, source locations or extraction offsets.
npm run generate runs one Python generator for all six languages. Each layout
becomes a reading function. Fields become direct primitive or object reads;
conditions, repetitions and discriminators become native control flow. Calls to
other layouts remain function calls, so shared layouts are not expanded at each
call site. The emitted code grows proportionally to the scheme.
The common compiler traversal lives in scripts/codegen/base.py; the language
backends alongside it emit syntax. scripts/reader_generators.py combines that
output with small runtime templates from scripts/templates. Those templates
handle binary primitives, buffers, reference bookkeeping and structural records.
No runtime interprets scheme instructions, predicates or type expressions, and
no reader needs the generator or the source scheme installed.
Use --scheme PATH --output-root DIR with scripts/generate-reader-assets.py
to generate readers for another extracted scheme without changing this checkout.
Custom schemes are a build-time input; decoding does not accept runtime scheme
injection.
The extractor includes inline serializers, inheritance and tensor metadata helpers. Inherited serializers and template aliases are explicit layouts with call instructions; readers perform no C++ inheritance lookup. It derives operation dispatch families from CasADi's native dispatcher and plugin registrations from the source. No mathematical evaluation occurs.
Coverage is still experimental. Native plain/debug fixture pairs validate MX, SX, nested calls, mappings, constants, ONNX-backed functions and Resource streams. The debug files independently check serialized field names and primitive tags; ordinary undecorated files use the same layouts. Tests also exercise a new function discriminator added to the scheme, followed by regeneration and execution of all six implementations on ordinary and debug input.
This is not yet a guarantee that every CasADi class/version can be read. Unsupported lowering, missing field types, absent layouts and unknown discriminators fail explicitly. Current fixtures target the CasADi 3.8.1 source snapshot, little-endian protocol 3. Expanding coverage belongs in the scheme extractor and fixtures, followed by regeneration of the readers.
npm ci
npm run generate
npm run check:generated
npm test
npm run test:browser
npm pack
CI checks deterministic generation and tests the emitted assets before updating main. Browser tests serve the
extracted npm tarball over HTTP and verify one JavaScript request with no scheme
JSON or CasADi runtime request. Native CasADi is used only when regenerating the
fixtures, via scripts/generate-fixtures.py and the Resource fixture generator.
Other languages
Python is dependency-free: PYTHONPATH=python python3 -m casadi_reader model.casadi.
casadi_reader.read_casadi(path) returns the same typed records as JavaScript;
to_json(document) makes them portable to the viewer. Use lazy=True for byte
handles and keep their source open while reading them.
C and C++ have independent implementations in c/ and cpp/. Build them with
cmake -S . -B build, cmake --build build, and ctest --test-dir build.
The separate source archives require only their respective compiler. Platform
archives include the library, CLI and headers.
Install the pure Python reader with pip install casadi-reader.
Julia is a native implementation requiring only Julia’s standard library:
using Pkg
Pkg.add(url="https://github.com/casadi/casadi-reader", subdir="julia", rev="v0.2.1")
using CasadiReader
record = read_casadi("function.casadi")
For a standalone download, extract casadi-reader-julia.zip and call
push!(LOAD_PATH, "/path/to/casadi-reader-julia") before using CasadiReader.
No package-manager call or dependency download is needed.
MATLAB is implemented in .m files. Extract the MATLAB ZIP, add its directory
to the MATLAB path, and call casadi_reader.read('function.casadi'). It needs no
MEX file, compiler, shared library, Python, or CasADi runtime. Use
casadi_reader.Document(path, '', true) for lazy byte payloads.
The generator consumes only the current prototype scheme format. There is no compatibility layer for earlier incarnations. CasADi resolves template types and member references; this project compiles those explicit layouts into code.
CI compares all languages against the same ordinary/debug fixtures, tests installed Python wheels and sdists, and tests the standalone Julia/MATLAB archives. C and C++ are built and tested separately on Linux, macOS and Windows.
Standalone downloads
CI attaches these ZIPs to each release:
casadi-reader-python.zip: extract and add its directory toPYTHONPATH; runpython -m casadi_reader model.casadi. No pip installation is needed.casadi-reader-javascript.zip: importdist/index.jsdirectly, or runnode bin/casadi-reader.js model.casadi. No npm installation is needed.casadi-reader-julia.zip: add the extracted directory to Julia'sLOAD_PATH.casadi-reader-matlab.zip: add the extracted directory to the MATLAB path.casadi-reader-c.zipandcasadi-reader-cpp.zip: independent source packages.casadi-reader-c-PLATFORM.zipandcasadi-reader-cpp-PLATFORM.zip: built command-line tools, shared libraries and headers for each supported platform.
Python wheels/sdists and npm publication remain available alongside these ZIPs.
Publishing
publish.yml publishes on a published GitHub release, after tests. The release
tag must equal v plus the package version. Prereleases use npm's next tag;
stable versions use latest.
The npm Trusted Publisher configuration is GitHub organization casadi,
repository casadi-reader, workflow publish.yml, with no environment name and
with direct npm publish allowed. Publishing uses OIDC and provenance, with no
npm token secret. See npm's documentation.
The reader implementation is MIT licensed. The vendored scheme is derived from CasADi; upstream attribution and license texts are retained in NOTICE and LICENSES.
Python and other language releases
The publish.yml workflow builds every distribution in CI. It publishes the
Python wheel and sdist with PyPI Trusted Publishing using environment pypi,
and attaches Julia, MATLAB, C and C++ packages plus checksums to the GitHub
release. The PyPI publisher identifies owner casadi, repository
casadi-reader, workflow publish.yml, and environment pypi.
All language metadata must match package.json; scripts/check-version.py
checks this before publication. scripts/package-bindings.py builds source
archives without requiring CasADi or a native compiler.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file casadi_reader-0.2.2.tar.gz.
File metadata
- Download URL: casadi_reader-0.2.2.tar.gz
- Upload date:
- Size: 88.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0e2f312f3ee2c71c21855bcd4e330ce50743e339e92a4902cedfcb95285d7bac
|
|
| MD5 |
48bfb235e91b012bf4af2ce27dd7cc03
|
|
| BLAKE2b-256 |
24ad52d1704bd0b51f63967a46d2b52b46669745a57a8d41f2756fcc3f652a42
|
Provenance
The following attestation bundles were made for casadi_reader-0.2.2.tar.gz:
Publisher:
publish.yml on casadi/casadi-reader
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
casadi_reader-0.2.2.tar.gz -
Subject digest:
0e2f312f3ee2c71c21855bcd4e330ce50743e339e92a4902cedfcb95285d7bac - Sigstore transparency entry: 2857454011
- Sigstore integration time:
-
Permalink:
casadi/casadi-reader@008faaab75a739bd06ac221534f28866ce1bb8ae -
Branch / Tag:
refs/tags/v0.2.2 - Owner: https://github.com/casadi
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@008faaab75a739bd06ac221534f28866ce1bb8ae -
Trigger Event:
release
-
Statement type:
File details
Details for the file casadi_reader-0.2.2-py3-none-any.whl.
File metadata
- Download URL: casadi_reader-0.2.2-py3-none-any.whl
- Upload date:
- Size: 46.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
63449d6afd4503911722ebdd311a32e270bfe2c7922639d65d7a92b15eabe0c2
|
|
| MD5 |
18198aa5feb2f8700812d717852d80f6
|
|
| BLAKE2b-256 |
586a040af10c6a4ca150e02a50b6c507772f7bfb44eccc7baf03007462ee26fc
|
Provenance
The following attestation bundles were made for casadi_reader-0.2.2-py3-none-any.whl:
Publisher:
publish.yml on casadi/casadi-reader
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
casadi_reader-0.2.2-py3-none-any.whl -
Subject digest:
63449d6afd4503911722ebdd311a32e270bfe2c7922639d65d7a92b15eabe0c2 - Sigstore transparency entry: 2857454372
- Sigstore integration time:
-
Permalink:
casadi/casadi-reader@008faaab75a739bd06ac221534f28866ce1bb8ae -
Branch / Tag:
refs/tags/v0.2.2 - Owner: https://github.com/casadi
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@008faaab75a739bd06ac221534f28866ce1bb8ae -
Trigger Event:
release
-
Statement type: