Ecosystem Interchange Profiles
voiage.ecosystem_integration provides repository-defined interchange
profiles. Legacy class and method names are retained for compatibility, but
they do not establish compatibility with external products.
Supported profiles
Section titled “Supported profiles”| Surface | Supported contract | Boundary |
|---|---|---|
| Decision-tree XML | .voiage.xml |
Repository-authored profile; TreeAge import/export and round trips are not verified |
| R-inspired records | JSON | BCEA- and hesim-inspired shapes; native R objects and RDS are unsupported |
| Tabular data | CSV, JSON, Parquet, .xlsx |
Excel OpenXML requires voiage[excel]; legacy .xls is unsupported |
Install Excel support explicitly:
pip install "voiage[excel]"The machine-readable boundary is
specs/integrations/ecosystem-interchange-profiles-v1.json.
An external product name may be promoted to a compatibility claim only after a
rights-cleared fixture from a pinned producer version passes an executed
producer-to-voiage round trip.
Tabular dtype and missing-value policy
Section titled “Tabular dtype and missing-value policy”CSV and Parquet use the same Polars adapter for the ecosystem connector, HEOML artifacts and widget CSV uploads. They preserve column order and the public connector payload keys, shape tuple and automatic classification.
| Input | Dtype policy |
|---|---|
| CSV | Inspect every row with infer_schema_length=None; do not infer dates. Keep mixed numeric/text columns as strings. Promote nullable integer columns and non-empty all-null columns to Float64, matching the previous reader. A header-only column remains an empty string column. |
| Parquet | Use the file’s declared Arrow schema and validity bitmap. Do not infer or coerce column types. Index fields identified by producer metadata stay outside the data columns. |
| JSON | Preserve the existing nested/flat JSON payload; no dataframe inference is performed. |
| Excel | Read raw cells with python-calamine and infer complete columns in Polars. Preserve typed headers, mixed cell scalars, leading blank areas, worksheet order, dates and time-only values. |
CSV recognizes the established missing-token vocabulary, including empty
fields, NA, NULL and NaN. Blank physical lines are skipped; quoted
newlines and genuine records of empty fields remain records. Numeric-looking
values in a mixed text column remain text, including when the text appears
after the first 100 rows. Nullable integer promotion retains the existing
floating-point representation; it does not promise arbitrary-precision integers.
Polars nulls and floating-point NaNs are distinct inside a Parquet frame. Arithmetic propagates a null as null and a NaN as NaN. A native nullable sum can return zero for an all-null column without filling its rows; a sum containing NaN remains NaN. These are transport-frame operations, not replacements for VOI numerical methods. No reader imputes, drops or fills missing samples.
The connector’s row dictionaries retain the existing NaN representation for
missing scalars. missing_values counts both nulls and NaNs. CSV export writes
both as empty fields using the existing quoting, floating-point spelling and
platform newline convention. Reloading CSV therefore preserves missingness,
but cannot recover the distinction between an Arrow null and a floating NaN.
Parquet retains that distinction. JSON parsing and export keep their existing
behavior, including Python’s existing NaN serialization behavior.
The numerical boundary remains unchanged: ValueArray.from_polars rejects
nulls, while strict numerical entry points such as evpi reject non-finite
NumPy values with non_finite_value. A caller must explicitly resolve missing
observations before analysis; loading data is not numerical acceptance.
Excel support uses python-calamine for reading and XlsxWriter through
DataFrame.write_excel for writing. Neither path falls back to a legacy dataframe engine or
openpyxl. Install voiage[excel] for both engines; without the required engine,
the connector warns with that installation diagnostic and retains its existing
empty-result behavior. The reader selects the first worksheet, ignoring chart
sheets, and retains blank rows inside the used area. Missing tokens follow the
CSV vocabulary. Homogeneous numeric and Boolean columns retain the previous
inference policy; mixed cell columns retain their individual scalar types.
Exports retain ordered worksheets, plain headers, general number formats,
blank missing cells, literal URLs and formula cells with empty cached values.
Positive and negative infinity remain the strings inf and -inf. Engine
changes do not promise identical ZIP bytes. Workbook handles close on success
and failure. Python 3.15.1 qualification uses frozen synthetic workbooks and
an independent openpyxl test oracle; openpyxl is not a runtime Excel dependency.
The reader preserves whitespace-only and padded text cells even when producers
omit xml:space="preserve". A secure streaming XML pass prepares an owned,
disk-backed temporary archive before native reading; it does not change the
source workbook or retain the archive in memory. Temporary files close and
are removed on success and failure. Padded numeric text still follows the
legacy full-column numeric inference policy.