Skip to main content

Offline, one-way, no-in-place migration tools for legacy nirs4all artifacts.

Project description

nirs4all-tools

Offline, one-way, no-in-place migration tools for legacy nirs4all artifacts (workspaces, .n4a bundles, loose prediction files).

This is the standalone home for the legacy readers that used to live inside the nirs4all runtime. The V1 runtime carries no legacy reader and no auto-migration trigger; instead, nirs4all-tools converts old stores into the format the runtime already reads (nirs4all-workspace-v2), so users keep their predictions/pipelines without the runtime ever opening a legacy store.

Status: first transform (lane L18, lock LOCK-MIG, decision DEC-MIG-001). The CLI surface, the no-in-place safety machinery, detection, the contract vocabulary, inspect, migrate --dry-run, and --copy-only are implemented. The first schema transform lowers sqlite-workspace-legacy-arrays metadata into a fresh workspace-v2 store.sqlite; legacy array rows are lowered into runtime-readable arrays/<dataset>.parquet sidecars when the optional parquet extra is installed, and the raw rows are still preserved as checksummed JSONL audit provenance. A native-results-v1 preview can lower one current dag-ml native results directory into runtime-readable workspace-v2 metadata plus array sidecars after strict hash/schema preflight. A legacy runs/*/*/manifest.yaml preview can lower one completed run when it references one complete *_predictions.json payload and the YAML/JSON metadata agree.

The one contract: no-in-place

Every command guarantees the source is never modified:

  • the source is opened read-only (SQLite via file:…?mode=ro&immutable=1);
  • --output is mandatory and must be disjoint from the input (aliasing / nesting is refused, exit 40);
  • the output must be empty unless --resume;
  • the whole source tree is snapshotted (path, size, mtime_ns) before and after every run — including failure and abort paths — and asserted byte-for-byte identical (a mismatch is exit 70).

Install

pip install -e ".[dev]"          # scaffold core is pure standard library
pip install -e ".[duckdb]"       # add DuckDB-source reading (optional)
pip install -e ".[parquet]"      # add Parquet lowering/validation (optional)

CLI

nirs4all-tools --version

# Read-only: detect what a legacy location contains.
nirs4all-tools legacy inspect <input> [--format json|text] [--report PATH]

# Convert into a fresh output (one-way, no-in-place).
nirs4all-tools legacy migrate <input> --output DIR --target nirs4all-workspace-v2 \
    [--manifest PATH] [--report PATH] [--id-map PATH] [--unsupported-report PATH] \
    [--checksums sha256] [--dry-run | --verify] [--strict | --best-effort] \
    [--copy-only] [--resume] [--trusted-load-joblib]

# Verify an output against its manifest (reads no source).
nirs4all-tools legacy verify <output-dir> --manifest PATH [--report PATH]

Current schema-transform support is intentionally narrow:

  • sqlite-workspace-legacy-arrays metadata is lowered to store.sqlite schema v2;
  • the legacy prediction_arrays table is decoded offline, lowered to the runtime array sidecar schema (arrays/<dataset>.parquet), and also preserved in preserved/legacy-prediction-arrays.jsonl for audit;
  • one standalone current dag-ml native-results-v1 directory with a valid score_set_hash and canonical predictions.parquet projection is lowered to workspace-v2 run/pipeline/chain/prediction/artifact metadata plus runtime-readable arrays/<dataset>.parquet sidecars; the original native payload is still checksummed under preserved/native-results-v1/;
  • malformed, older, mixed, or multi-artifact native-results-v1 sources fail --strict with a machine-checkable schema/preflight cause, and best-effort mode preserves them opaque with the same reason in the manifest;
  • one standalone complete *_predictions.json loose-prediction payload is lowered to workspace-v2 run/pipeline/chain/prediction metadata plus runtime-readable arrays/<dataset>.parquet sidecars when the parquet extra is installed; the original loose JSON and sibling metadata files are still checksummed under preserved/loose-predictions/;
  • one standalone legacy runs/*/*/manifest.yaml tree is lowered when its single manifest points to one complete *_predictions.json under the same source root and run_id, pipeline_id, dataset, model, and preprocessing metadata match; the manifest tree and referenced prediction payload remain checksummed under preserved/;
  • .n4a, .n4a.py, and non-lowerable native-results-v1 artifacts are preserved as opaque checksummed payloads under preserved/ with an empty workspace-v2 store;
  • non-lowerable legacy workspace payloads such as store.duckdb, legacy runs/ trees outside the single-manifest preview, incomplete or mixed loose prediction files, and already-v2 SQLite stores are also preserved opaque by default in best-effort mode; --strict refuses them before writing;
  • every real migration writes unsupported-report.json alongside the manifest, report, and id-map; dry runs write the same machine-readable unsupported report only when --unsupported-report PATH is provided;
  • best-effort migration exits 10 only when semantic lowering is unavailable and content must be preserved opaque;
  • --strict requires semantic lowering and exits 0 for fully lowered array sources or native-results metadata previews.

Exit codes

Code Meaning
0 success, no warnings
10 migrated with warnings (best-effort preserved opaque / non-fatal skips)
20 unsupported input (unknown / forward-version source, or strict unsupported item)
30 verification failed
40 refused by policy (in-place / aliased output, non-empty output without --resume)
70 internal error (incl. source-tree integrity assertion failure)

Contracts

Four durable JSON contracts are emitted alongside a migrated workspace (SW4_MIG_CONVERTER_spec.md §7–10):

  • legacy_migration_manifest.v1 — the exhaustive inventory + checksum + id-map ledger;
  • legacy_migration_report.v1 — the human/UX digest + next action;
  • legacy_id_map.v1 — the never-lossy old→new id map.
  • legacy_unsupported_report.v1 — the machine-readable list of unsupported, refused, or opaque-preserved items.

Development

ruff check .
mypy
pytest

Checked-in converter goldens live under tests/fixtures/legacy/. They are small reduced legacy payloads for old workspaces, run/pipeline manifests, and prediction arrays. Tests copy or materialize them into temporary directories before migration so the source goldens stay read-only and the no-in-place contract remains observable.

License

Dual-licensed CeCILL-2.1 OR AGPL-3.0-or-later (plus commercial), consistent with the nirs4all ecosystem policy. See LICENSE. Contact: nirs4all-admin@cirad.fr.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

nirs4all_tools-0.0.4.tar.gz (63.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

nirs4all_tools-0.0.4-py3-none-any.whl (52.3 kB view details)

Uploaded Python 3

File details

Details for the file nirs4all_tools-0.0.4.tar.gz.

File metadata

  • Download URL: nirs4all_tools-0.0.4.tar.gz
  • Upload date:
  • Size: 63.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for nirs4all_tools-0.0.4.tar.gz
Algorithm Hash digest
SHA256 a8320ae7e0683697e98259db7c62073c0c328717a52b5b972837f52b3c595bf7
MD5 b170863fb38afe278d0f1eea3dbdf3ea
BLAKE2b-256 88090565884803ac844f7b350247013cd011b15e2aa00336496cf09b5c2d8edc

See more details on using hashes here.

Provenance

The following attestation bundles were made for nirs4all_tools-0.0.4.tar.gz:

Publisher: publish.yml on GBeurier/nirs4all-tools

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file nirs4all_tools-0.0.4-py3-none-any.whl.

File metadata

  • Download URL: nirs4all_tools-0.0.4-py3-none-any.whl
  • Upload date:
  • Size: 52.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for nirs4all_tools-0.0.4-py3-none-any.whl
Algorithm Hash digest
SHA256 7f4d17544e799994b32b8c9caf7c0ceba164afdf917f8faf0c6362e089d4b6b8
MD5 8e0cc4f676ec2f78a118810beca9e516
BLAKE2b-256 79997a9b2a60b31d1291dbac9162f8be98fd35be05e5442b745541e8462b9ed4

See more details on using hashes here.

Provenance

The following attestation bundles were made for nirs4all_tools-0.0.4-py3-none-any.whl:

Publisher: publish.yml on GBeurier/nirs4all-tools

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page