Python extension contract¶
This page is the detailed contract of the compiled Python module ras_commander_fast_hdf
(the ras-commander-fast-hdf wheel): how it is built and identified, every group of
bindings and the shape of what they return, how errors and panics reach Python, and which
licences the wheel ships. The module is an internal building block: applications normally
use ras-commander's Hdf* classes and its fast_hdf adapter, which decide between this
module and h5py. The current binding contract is API_VERSION 11, built against engine API
10 from this repository. An overview is in ../python-extension.md;
the API version history at the end lists what each version added.
Build and identity¶
The engine is a Cargo path dependency (../crates/ras-commander-rust) declared in
python/Cargo.toml. The main ras-commander package remains installable without a Rust
compiler; wheels are built by CI (see ../releasing.md). To build locally,
use a Rust toolchain with an installed platform linker and Python 3.10 or later, from the
repository root:
uv tool run --from maturin maturin build --release --locked --manifest-path python/Cargo.toml
uv pip install --python <your-python> <resulting-wheel>
cargo test --locked --manifest-path python/Cargo.toml
Set CARGO_TARGET_DIR to a local directory rather than placing build outputs on a network
share. Windows needs the Visual Studio C++ Build Tools. PYO3_PYTHON can select the
interpreter explicitly. The wheel uses the CPython 3.10 stable ABI; cross-platform
compatibility is tested per platform. extension-module is enabled by maturin, while plain
cargo test links Python normally. The minimum supported Rust version is 1.88.
| Name | Meaning |
|---|---|
API_VERSION |
Binding contract version (11). One Rust constant; ras-commander requires an exact match. |
TEXT_API_VERSION |
Version of the RAS text-file bindings (1). |
ENGINE_COMMIT |
Commit of this repository the wheel was built from (git rev-parse HEAD), or the 40-digit value of RAS_ENGINE_COMMIT when set (for builds from a source archive), else "unknown". |
ENGINE_FEATURES |
Engine Cargo features, read from the dependency declaration in python/Cargo.toml: ("catalog", "hdf", "mesh", "results"). |
python/build.rs parses Cargo.toml as TOML and fails the build with an explicit error if
the ras-commander-rust dependency is not the in-repository path or lacks a features
array. Cargo.lock freezes resolution.
capabilities() returns the engine commit and feature list, engine_api_version,
engine_capabilities (the engine's compiled features and owner/name/feature entry points),
default_max_bytes, and bindings: the sorted set of actually registered functions and
classes (including the NativeAnalysis class, excluding exception classes), so optional
feature builds report only what was registered. ras-commander's tests check this set
against an explicit expected list (78 entry points at API 11, including the
_panic_for_test hook).
Core numeric, mesh and tile functions¶
read_numeric(path, dataset_path, selection=None, threads=None, parallel=True)
read_numeric_batch(path, dataset_paths, threads=None, parallel=True)
assemble_cells(face_points, face_endpoints, face_perimeter_info,
face_perimeter_values, cell_face_info, cell_face_values,
threads=None, *, strict=True, return_diagnostics=False)
write_pmtiles(layers, output, min_zoom, max_zoom, threads=None)
File arguments accept str or os.PathLike.
Numeric reads¶
Numeric reads return NumPy arrays with their native numeric dtype and original rank.
Supported types are signed/unsigned 8/16/32/64-bit integers and 32/64-bit floats in native
byte order. Other datatypes and non-native byte order raise UnsupportedError; use h5py
for those. A selection is a list of nonnegative (start, stop, step) triples, one per axis,
with positive steps and exclusive stops; bounds must already be normalized. Integer axis
squeezing and arbitrary advanced indexing belong to the Python adapter. Batch reads reuse
one file context and return a dictionary keyed by dataset path; repeated identical paths
collapse to one key (the last returned value wins). Arrays own their memory after return
and do not depend on an open HDF handle.
Since engine API 10, read_numeric, read_numeric_batch and read_topology (used by
HdfSession numeric reads and the reader) refuse more than DEFAULT_READ_MAX_BYTES
(2 GiB) of decoded values before allocating. auto mode falls back to h5py for such reads;
required-native (native) mode raises FastHdfError. The engine's additive *_bounded
variants are not bound yet.
Mesh cell assembly¶
Mesh inputs are two-dimensional NumPy arrays: coordinates are float64 and
indices/offsets are int64. Coordinates have two columns. Face endpoints and perimeter
info have at least two columns; cell face info has at least two; cell face values have at
least one (face ID). The kernel accepts strided arrays and copies inputs before releasing
the GIL, protecting against concurrent mutation of borrowed Python memory. Output is
(coordinates, offsets, cell_ids): float64 coordinates of shape (N, 2), int64 offsets
of length C+1, and int64 original cell IDs of length C. Each offset interval contains
one closed ring.
Assembly follows face endpoint connectivity, reversing complete face chains when
necessary. Every intermediate perimeter coordinate is retained. Zero-face cells and
one-open-face boundary ghost cells are omitted without renumbering. Disconnected,
branching, self-loop or unclosed topology raises TopologyError; the Python compatibility
path can polygonize such cases. This kernel handles simple single-ring cell boundaries,
not arbitrary polygonization or automatic geometry repair.
Native diagnostics (return_diagnostics=True) are dictionaries with
subject/message/capability plus context fields; cell omissions add cell_id/kind.
The ras-commander adapter preserves its public polygon diagnostic records and exception
types. Engine string-only diagnostics carry an explicit unavailable capability whose
reason states that typed capability evidence was not supplied; prose is never classified.
Since engine API 10, mesh cell polygon rings follow the ras-commander Python contract
(clockwise, starting at the first listed face), so mesh_polygons and the Python
HdfMesh.get_mesh_cell_polygons agree byte for byte (see
engine-api.md).
PMTiles¶
write_pmtiles takes a list of dictionaries with keys:
name: unique nonempty layer name.coordinates:float64(N, 2)WGS84 longitude/latitude coordinates.offsets:int64ring offsets, lengthC+1.cell_ids:int64nonnegative IDs unique within the layer.properties: dictionary of column names to Python lists of lengthC.
Property values are strings, signed 64-bit integers, floats, booleans or None.
Non-finite property floats become null; out-of-range integers raise. Coordinates must be
finite and within Web Mercator latitude limits. pyproj transforms the packed coordinate
arrays outside this kernel; no GeoJSON, WKB or GeoDataFrame serialization is required for
the native tile path.
The exporter writes MVT PMTiles, zooms 0-22, with dropping, clustering, coalescing and presimplification disabled. Clipping and MVT quantization still apply. The pinned freestiler encoder replaces a collapsed exterior with a one-pixel square at its centroid, preserving visibility rather than exact subpixel geometry. PMTiles are a visualization product; packed source polygons remain the analytical geometry. Source features remain in memory; upstream freestiler spools encoded tile chunks to temporary storage. The Python adapter supplies a staged output path and atomically publishes it after success; the underlying PMTiles writer also stages archive assembly before replacing its destination.
The native tile orchestrator uses freestiler's assignment, clipping, MVT, compression and
PMTiles writer kernels, inserting an integer-grid topology repair before compression. Real
BaldEagle exports exposed rounding-induced backtracking spikes and self-intersections
despite valid source polygons. Simple single-ring features bypass overlay; pathological or
multipart rings are reconstructed with i_overlay using nonzero winding. Splits remain
parts of the same feature with unchanged IDs and property tags. Repair operates on the
final tile grid, avoiding a second projection or quantization. Processing uses batches of
32 tiles and spools compressed output. Eight decoded real failures, with source
mesh/cell/tile metadata, are kept as compact Rust regression fixtures in
python/tests/quantized_regressions.json.
Threads¶
Expensive HDF reads, topology assembly and tiling release the GIL. Thread pools are reused
by effective thread count; at most eight configurations are cached. The default is the
smaller of eight and the available CPU count. Explicit threads values must be 1-1024.
Outer parallel workflows should set a smaller count to avoid oversubscription. Serial
numeric reads use parallel=False. Structure reads use threads=None and the shared
bounded reader thread validation. Sessions are described in sessions.md.
Errors¶
| Engine error | Python exception |
|---|---|
| NotFound (object) | KeyError |
| FileNotFound | FileNotFoundError, with filename and errno=2 |
| Io | OSError |
| Unsupported | UnsupportedError(ValueError) |
| InvalidRequest | ValueError |
| Corrupt | CorruptDataError(ValueError) |
| StructuralTopology / InvalidGeometry | TopologyError(ValueError), mesh_structure_error True / False |
| Internal / future kind | RuntimeError |
These exception types are exported by the extension. One central mapper, shared by the
reader and mesh bindings, attaches engine_kind (the engine's snake_case as_str()),
engine_code (the optional unsupported code), subject and source_path. Exception text
includes the engine kind prefix; callers should catch exception types rather than parse
strings. Annotation failure preserves the original exception rather than replacing its
category. Automatic fallback must never catch every exception indiscriminately or hide
corrupt inputs. ras-commander's public fast_* adapter failure policy and FastHdfError
wrapping are unchanged.
Panic containment¶
Every #[pyfunction] and #[pymethods] body runs inside panic_guard::guard
(catch_unwind). Without it, a Rust panic would surface as PyO3's PanicException, a
BaseException, which escapes an except Exception h5py fallback.
- With
ras_commander.fast_hdfimported, a panic raises itsFastHdfPanicError(FastHdfError):automode falls back to h5py, andnativemode reports aFastHdfError. - The standalone module raises
NativePanicError(RuntimeError).
HdfSession catches engine panics while it holds its lock, and recovers a poisoned lock. A
panic therefore never disables a session: later reads, closed and close() keep working,
including on process-cached sessions.
_panic_for_test(message) and HdfSession._panic_for_test() inject a panic for tests
(used by ras-commander's tests/rust_engine_bridge/panic_guard_test.py).
Aborts (stack overflow, allocation failure) cannot be caught in-process. The engine
prevents those on file input with read budgets and malformed-input hardening (see
engine-api.md and vendor/hdf5-reader/PROVENANCE.md): bounded
soft-link resolution, decoded chunk size bounded before allocation (256 MiB default),
checked size arithmetic, chunk-cache recovery after a decoder panic, and attribute element
counts checked against their payload.
Wire conventions¶
These apply to every typed binding below.
- Module functions are path-first.
max_bytesandmetadata_max_bytesdefault to the engine'sDEFAULT_MAX_BYTES(67108864, 64 MiB); defaults are compile-time checked against the engine constant. They keep the engine meaning (each raw stored object, or the selected output), not an aggregate memory limit; the engine's 8 MiB profile/packed-name exception remains. - Capability dictionaries have exactly
status/code/reason, using the engineas_str()spellings. - Evidence dictionaries (
Reported<T>) containkind/value/raw_bytes/capability, or{capability, value}for typed values.kinddescribes evidence, not a competing availability status. Raw bytes may beNonewhere the engine supplies none. - Identities are
{source, table, row}plus existing domain names; compatibilityindex/source/pathaliases remain where already exposed. - Enum strings come from engine methods. Structure kind preserves
f32/f64wire names, whiledtypeuses the common NumPy dtype spelling. - Compounds are
{shape, raw_bytes, columns}with exact stored bytes and typed column metadata; Python scalar lists are decoded views, not float-bit oracles. - Numeric arrays keep their stored NumPy dtype; buffers move into NumPy without float widening. Selections retain element order and duplicates. Read results are owned NumPy arrays; other reports use plain dict/list/bytes values.
- Floating metadata preserves Python float NaN and infinity (not coerced to null), so these values are not strict JSON; serialize with an explicit missing-value policy.
- Diagnostics share
subject/message/capabilityfields;Nonemeans the engine supplied no evidence, and no status is inferred from diagnostic prose. - Column labels expose
source_attribute(sourceremains an alias). Dataset results exposedataset_pathalongside thedataset/pathkeys.
Metadata, CRS and cross-section bindings¶
numeric_capability(path, dataset_path)
temporal_reduce(path, dataset_path, offset=None, threshold=None,
max_block_bytes=16 << 20, threads=None, parallel=True)
raw_crs_evidence(path)
typed_group_attributes(path, group="/")
mesh_inventory(path, max_bytes=67108864)
mesh_name_diagnostics(path, max_bytes=67108864)
cross_sections(path, max_bytes=67108864)
plan_result_mode(path)
steady_profile_names(path, max_bytes=67108864)
read_cross_section_result(path, kind, variable, rows, sections,
max_bytes=67108864, threads=None, parallel=True,
*, metadata_max_bytes=67108864)
plan_capabilities(path, max_bytes=67108864)
rows/sections are (start, exclusive_stop, positive_step); kind is
steady/unsteady; variable is Water Surface/Flow; max_bytes bounds selected
returned bytes. Attribute types and capability status/code/reason are explicit; raw bytes
remain available for unsupported/corrupt attributes. CRS statuses are raw lexical evidence:
capability Supported means lexically readable text only, never a validated semantic CRS or
an EPSG/authority. exact_wkt is kept verbatim, including when a lexical capability
refuses it. Hydraulic-unit evidence is separate. Cross-section identities and bank/name
field availability keep engine semantics. Plan capabilities never certify solver success;
plan_capabilities includes structures (per-family capability, datasets, diagnostics)
and maps boundary_conditions/calibration_regions alongside reference lines and points.
mesh_inventory delegates the canonical engine inventory: physical/stored/ghost counts,
per-variable capability, legacy results and output_blocks with
mode/block_name/dataset_root/results. Names-only layouts fail closed.
mesh_name_diagnostics returns mesh_name plus typed issue strings missing_group,
extra_group, duplicate_attribute_name and invalid_name; inventory disagreement raises
CorruptDataError, never a partial successful inventory. Steady absence versus
unsupported layouts and block corruption follow engine capabilities.
temporal_reduce uses the engine's output.chunk_shape and output.values
rows/maximum length, without a second numeric_capability query. chunk_shape None
covers layouts with no chunk dimensions; it does not promise support for every
compact/virtual layout.
Time and unit bindings¶
unsteady_time_axis(path, max_bytes=67108864)
unsteady_row_times(path, rows, max_bytes=67108864)
result_units(path, max_bytes=67108864)
dataset_unit_evidence(path, dataset)
Time dictionaries keep raw_strings, raw_ms_strings, raw_ms, days,
ms_since_epoch, timestamps (ISO-like .mmm strings with no zone), hour_2400_rows and
capability. Axis reports include group, rows, epoch=civil_unix_1970 and
ms_source; selections report the original row_indices and selected hour-2400 indices
(not renumbered). timezone is None, never UTC: the epoch is a civil 1970 origin, not a
UTC instant. Integer-ms sources keep a separate integer_ms Unsupported capability; no
epoch is invented from raw integers. If valid stamp strings independently prove civil
timestamps, overall capability is Supported while integer_ms still reports its
limitation. Days-only axes remain unsupported for civil conversion. Selection validates the
full axis under max_bytes, then applies (start, stop, step).
Unit dictionaries include status, text, raw_bytes, capability,
source_attribute, quantity_name and unit_system_kind where relevant. result_units
returns variables (family, area, variable, dataset, units) and unit_system evidence
(source group, kind, value). dataset_unit_evidence delegates the engine's
dataset_units, keeping its Python name. Known quantity labels and exact source text come
from the engine; the binding does not normalize units, infer CRS, resolve unit-system
conflicts or convert numeric values.
Structure bindings¶
structure_inventory(path, family, max_bytes=67108864)
read_structure_series(path, family, structure, relative, rows, columns,
max_bytes=67108864, threads=None, parallel=True)
Family keys: sa_2d_area_connection (canonical; sa2d_area_connection is accepted as a
compatibility alias), lateral_structure, storage_area. Rows/columns are
(start, stop, stride). structure=None selects only storage-area family series. The
inventory returns the source group, time_rows, identities, Node Pointer evidence, series
shape/kind/capability, exact label bytes and units, static dataset paths and label
diagnostics. A successful inventory status certifies the engine's layout validation, not
every column-label table; per-series columns and inventory diagnostics keep
unsupported/corrupt label evidence. No identity, unit or absent series is invented. Reads
keep f32/f64 dtype, shape and bit values, engine path validation, explicit byte
budgets and the standard error mapping. ras-commander's tests use the engine's
crates/ras-commander-rust/tests/fixtures/structures fixtures, whose manifest is the hash
oracle.
Mesh result and geometry bindings¶
Implemented in python/src/fim.rs: mesh summary, series and boundary-condition
inventories and reads, extrema with first stored indices, geometry arrays and packed
families, exact identity comparison, layer inventory and typed run-summary attributes;
plus mesh_geometry (field descriptors), mesh_geometry_tables (exact Attributes compound
and Cell Info), geometry_family_capability and mesh_boundary_links. Semantics are the
engine's (mesh-results.md, engine-api.md). Mesh series
descriptors and catalogue mesh-result layers carry domain_rule (stored_location,
legacy_exact_name, labelled_summary, boundary_columns, unqualified).
1D bindings¶
Implemented in python/src/one_d.rs: xs_geometry_inventory, read_xs_geometry,
one_d_line_family, river_reaches, river_junctions, xs_interpolation_surfaces,
xs_result_inventory, read_xs_result, unsteady_row_window, one_d_summary_inventory,
read_one_d_summary, structure_geometry, one_d_geometry_group, pump_stations,
one_d_structure_inventory, one_d_structure_capabilities (with the engine
OneDStructureKind::qualified flag) and read_one_d_structure_series. Semantics are in
one-d.md.
Read family bindings¶
Implemented in python/src/wave3.rs:
| Binding | Engine API | Returns |
|---|---|---|
read_families() |
READ_FAMILIES |
family names (pipe_geometry, pipe_results, reference_line_results, reference_point_results, breach, plan_metadata, land_cover, infiltration, sediment, encroachments, terrain, event_conditions, steady_output, terrain_modifications, ...) |
read_family_inventory(path, family, metadata_max_bytes) |
read_family_inventory |
{family, capability, datasets, groups}; each dataset has path, identity, shape, kind/dtype, storage, capability, typed attributes, role, domain, time_group, identity_table, locations, names, geometry_locations, stored_location_ids (stored-dtype array or None), time_of_extreme_row |
read_family_dataset(path, family, dataset, slices=None, metadata_max_bytes, max_bytes) |
read_family_dataset |
stored values (below) |
output_block_inventory(path, max_bytes) |
output_block_inventory |
non-Base blocks with stored descriptors |
read_output_block(path, block, relative, slices=None, max_bytes) |
read_output_block |
stored values |
reference_point_geometry(path, max_bytes) |
reference_point_geometry |
Reported: Attributes compound, Points array, features (identity, name, area, stored i32 cell_index, point_row) |
classification_catalogue(path, family, max_bytes) |
classification_catalogue |
Reported: layout, entries (pixel_id as stored int, name, variable_rows, capability), unmatched_variables |
stored_family_index(path, metadata_max_bytes) |
all family inventories + output blocks | compact routing index: {datasets: [{owner, path, storage, shape, dtype, status, code}], failures, output_blocks} |
Stored values are {"storage": "numeric", "values": ndarray} (stored dtype),
{"storage": "compound", "values": {shape, raw_bytes, columns}},
{"storage": "bitfield_bytes", "shape", "raw_bytes"} (exact bytes; h5py reads these
1-byte bitfields as uint8) or {"storage": "strings", "shape", "values"} (engine-decoded
text, trailing NULs removed). Slices are (start, stop, step) per dimension and apply to
numeric storage only. Family-level errors in stored_family_index are reported in
failures, never dropped; the ras-commander router also surfaces them in required-mode
refusals and in its trace.
Typed attribute and raw string bindings¶
| Binding | Engine API | Returns |
|---|---|---|
typed_dataset_attributes(path, dataset, max_bytes) |
typed_dataset_attributes |
{capability, value}; value is a list of typed attributes (as typed_group_attributes) for any dataset, inside or outside the read families. Absent dataset: Unavailable; group path: invalid_request |
raw_fixed_strings(path, dataset, max_bytes) |
raw_fixed_strings |
{capability, value: {shape, dataspace, width, padding, charset, raw_bytes}}: stored bytes with padding kept (h5py's bytes follow after the NULLPAD conversion) |
Every typed attribute carries dataspace (scalar, simple or null; null is h5py
Empty), and bitfields are attribute_type = {kind: "bitfield", bytes, byte_order} with
the exact stored bytes as value. Compound tables and stored family datasets carry
dataspace.
How ras-commander routes reads¶
These behaviours live in ras-commander's Python adapter, not in this module, but they define how the bindings are used:
fast_hdf.read_datasetdispatches bounded Base Output summary, series and BC reads to the typed readers under the backend policy. Explicit thread controls and reads larger than the typed budget keep the generic native reader. Metadata, geometry construction, ghost filtering, timestamps and public exceptions stay in the Python adapters; h5py remains the automatic unsupported fallback. HEC-RAS 7.0Cell Hydraulic Depthis passed through exactly (noDepthalias); the xarray name normalizer only lowercases and replaces punctuation and spaces (cell_hydraulic_depth).fast_hdf.read_typed(ras_commander/_fast_hdf_typed.py) usesstored_family_indexas the membership oracle for datasets outside the mesh-geometry and 1D routes: supported numeric, compound and bitfield datasets are read typed; listed-but-unqualified datasets (for example Davis pipe summaries with no storedLocation) keep their exact literal values through the generic reader; strings stay on h5py (the documented metadata exception), because decoded text cannot prove h5py's fixed-length bytes. Compound members stored NULLTERM or SPACEPAD are converted the way HDF5 converts them into h5py's NULLPAD memory type (cut at the first NUL / strip trailing spaces, zero-fill), from the engine's member padding evidence.- The Python temporal fallback supplies all timing and read-plan keys, with NaN for
unavailable setup/splits and a
timing_scopeexplaining the combined measurement. Native setup is measured; both backends exposeengine_seconds.parallelis forwarded to the native session and reduction; the Python fallback is serial. Fallbackread_plan.chunk_cache_bytesis the h5py/HDF5 configured raw-data chunk cache capacity; native reports the engine file cache's maximum capacity. These are distinct backend configurations, not measured bytes or process RSS, and their equality is not a parity promise; block plan/count/value and peak/count arrays are tested for parity. log_calllogs function names only and never formats array arguments or results.
Dependency provenance¶
hdf5-reader/hdf5-coreare vendored in this repository'svendor/directory and used by the engine, based on upstreamroteiro-gis/netcdf-rustat24ff6fcfcc79a35c30aa5d8cb3028ab4d9d00564,MIT OR Apache-2.0.vendor/hdf5-reader/PROVENANCE.mdandvendor/LOCAL_PATCHES.mdrecord the local changes. The extension has no direct generic-reader dependency.freestiler-core:walkerke/freestiler, revisionbeb64b0d4414da895ec67d02b2f91db6ab6acc37, MIT AND ISC. Its crate is unpublished; Cargo resolves the pinned Git source.- PyO3/rust-numpy provide the binding. ndarray allocations transfer to NumPy on numeric return. Owned input copies are intentional and are not zero-copy.
flate2enables zlib-rs. Cargo feature unification also enables upstreamrust_backend; flate2 selects the explicitly requested zlib-rs backend.i_overlay1.9.4 andi_float1.6.0 (already in freestiler's dependency tree) supply integer-grid repair; their licence notices are included.prostuses the same 0.13 version as freestiler, preserving MVT field representations.
python/Cargo.lock records exact transitive dependencies. Retain upstream licence notices
when distributing wheels. Source provenance of the extension and engine is in
provenance.md.
Licences¶
The wheel ships these files under .dist-info/licenses/, through maturin
license-files in pyproject.toml:
licenses/ras-commander-rust-LICENSE.txt: a copy of this repository's MITLICENSE(CLB Engineering Corporation). Keep it identical to../LICENSE.licenses/ras-commander-LICENSE.txt: the original ras-commander MIT notice (William M. Katzenmeyer), for the code extracted from ras-commander.- the other
licenses/*.txtper-crate notices. THIRD-PARTY-NOTICES.md: generated from the locked default-wheel graph (extension-module). It lists every crate linked for any target platform, with the full licence texts each crate ships. It includes the bundled zstd C library (BSD-3-Clause, elected from BSD-3-Clause OR GPL-2.0) and the Apache-2.0-onlyapproxandprost. Compile-time proc-macro crates (such asprost-derive) are listed too, marked as such.
Regenerate the notices after any change to python/Cargo.lock or the engine's
dependencies. From python/:
python scripts/generate_third_party_notices.py --features extension-module --own-licence ../LICENSE --title "ras-commander-fast-hdf wheel (default features)"
python scripts/generate_third_party_notices.py --features extension-module --own-licence ../LICENSE --title "ras-commander-fast-hdf wheel (default features)" --check
The script uses only the Python standard library and cargo metadata --locked, and is the
same as scripts/generate_third_party_notices.py at the repository root. A crate whose
published package ships no licence file needs its upstream texts under
scripts/licence-fallbacks/<crate>-<version>/, with a SOURCE.txt, and generation fails
until they are added. Wheels built with exports-* features link a larger graph:
regenerate with those features and add any missing fallbacks before distributing them.
Tested datasets, measured timings and limitations are in validation.md.
API version history¶
| API | Engine API | Added or changed |
|---|---|---|
| 5 | 5 | Hardened bindings: numeric_capability, temporal_reduce, raw_crs_evidence, typed_group_attributes, mesh_inventory, cross_sections, plan_result_mode, steady_profile_names, read_cross_section_result, plan_capabilities; central typed exception mapping; time/unit bindings and mesh_name_diagnostics; structure bindings; unified wire shapes (capability {status, code, reason}, Reported<T> evidence, {source, table, row} identities, snake_case enum strings, optional max_bytes defaults, dictionary diagnostics). |
| 6 | 5 | Mesh result and geometry bindings in src/fim.rs (45 entry points). |
| 7, 8 | 6 | Sessions (HdfSession, NumPy element/index outputs), cache controls (cache_bytes, cache_slots, cache_stats()), read_mesh_summary_values and read_mesh_boundary_batch; see sessions.md. |
| 9 | 7 | 1D bindings (src/one_d.rs) and the mesh-geometry tables, geometry family capability and boundary links (67 entry points). |
| 10 | 8 | Read family bindings (src/wave3.rs) and stored_family_index (75 entry points). |
| 11 | 9, then 10 | typed_dataset_attributes, raw_fixed_strings, dataspace and bitfield attribute types, domain_rule; panic containment and _panic_for_test (78 entry points). Built against engine API 10: ring-order contract, malformed-input hardening and the 2 GiB default read budget; bindings unchanged. |