nirs4all.pipeline.bundle.generator module

Bundle Generator - Export trained pipelines as standalone bundles.

This module provides the BundleGenerator class for exporting trained pipelines to various bundle formats (.n4a, .n4a.py) for deployment, sharing, or archival.

Bundle Formats:
.n4a: Full nirs4all bundle (ZIP archive) containing:
  • manifest.json: Bundle metadata and version info

  • pipeline.json: Minimal pipeline configuration / chain.json

  • trace.json: Execution trace for deterministic replay

  • artifacts/: Directory with artifact binaries

  • fold_weights.json: CV fold weights (if applicable)

.n4a.py: Portable Python script with:
  • Embedded artifacts (base64 encoded)

  • Standalone predict() function

  • No nirs4all dependency (only numpy, joblib required)

Supports two export paths:

  1. Store-based (preferred): export_from_chain(chain_id, output_path) loads the chain from WorkspaceStore and packages it into a bundle.

  2. Resolver-based: export(source, output_path) resolves from a prediction dict / folder / bundle and packages artifacts.

Example

>>> from nirs4all.pipeline.bundle import BundleGenerator
>>>
>>> # Store-based export (preferred)
>>> generator = BundleGenerator(workspace_path)
>>> bundle_path = generator.export_from_chain("abc123", "exports/model.n4a")
>>>
>>> # Resolver-based export
>>> bundle_path = generator.export(best_prediction, "exports/model.n4a")
class nirs4all.pipeline.bundle.generator.BundleFormat(value)[source]

Bases: StrEnum

Supported bundle export formats.

Variables:
  • N4A – Full ZIP bundle with all artifacts and metadata

  • N4A_PY – Portable Python script with embedded artifacts

N4A = 'n4a'
N4A_PY = 'n4a.py'
class nirs4all.pipeline.bundle.generator.BundleGenerator(workspace_path: str | Path, verbose: int = 0, store: Any | None = None)[source]

Bases: object

Generate standalone prediction bundles from trained pipelines.

This class exports trained pipelines to bundle formats that can be used for deployment, sharing, or archival without requiring the original workspace or full nirs4all installation.

Variables:
  • workspace_path – Path to the workspace root

  • resolver – PredictionResolver for resolving prediction sources

  • verbose – Verbosity level for logging

Example

>>> generator = BundleGenerator(workspace_path)
>>> generator.export(best_prediction, "model.n4a")
>>>
>>> # Export to portable script
>>> generator.export(best_prediction, "model.n4a.py", format="n4a.py")
export(source: dict[str, Any] | str | Path, output_path: str | Path, format: str | BundleFormat = BundleFormat.N4A, include_metadata: bool = True, compress: bool = True) → Path[source]

Export a prediction source to a bundle.

Parameters:
  • source – Prediction source (prediction dict, folder path, etc.)

  • output_path – Path for the output bundle

  • format – Bundle format (‘n4a’ or ‘n4a.py’)

  • include_metadata – Whether to include full metadata in bundle

  • compress – Whether to compress artifacts (for .n4a format)

Returns:

Path to the created bundle

Raises:
export_from_chain(chain_id: str, output_path: str | Path, fmt: str | BundleFormat = 'n4a') → Path[source]

Export a chain from WorkspaceStore as a standalone bundle.

This is the preferred export path. It reads the chain directly from the workspace store, collects all referenced artifacts, and packages them into the requested format.

Parameters:
  • chain_id – Chain identifier stored in WorkspaceStore.

  • output_path – Destination file path.

  • fmt – Export format ("n4a" or "n4a.py").

Returns:

Path to the created bundle file.

Raises:
  • RuntimeError – If no store was provided at construction time.

  • KeyError – If the chain does not exist.

nirs4all.pipeline.bundle.generator.write_single_model_bundle(model: Any, output_path: str | Path, *, model_label: str = 'model', pipeline_uid: str = '', preprocessing_chain: str = '', provenance: dict[str, Any] | None = None, extra_members: dict[str, bytes] | None = None, train_steps: list[Any] | None = None, compress: bool = True) → Path[source]

Write a minimal, valid .n4a ZIP bundle whose sole step is one predict-capable model.

Unlike BundleGenerator (which packages a workspace chain of per-step / per-fold artifacts resolved from a PredictionResolver), this writes a SELF-CONTAINED single-model bundle from one in-hand object: the bundle’s only step is model, whose predict(X) already performs the entire forward pass (feature transforms → estimator → optional y-inverse). It is the bundle-format counterpart of a bare joblib.dump(model) and needs NO workspace, store, resolver, or trace.

Its purpose is the dag-ml NATIVE .n4a export: a single-model dag-ml run captures its refit model as exactly such a predict-capable object (_DagmlExportedModel), and this packages it into a portable bundle WITHOUT re-fitting the pipeline on the legacy engine.

The output conforms to the EXISTING .n4a format (bundle_format_version BUNDLE_FORMAT_VERSION): a manifest.json with model_step_index == 1, a pipeline.json carrying a single model step, and one artifacts/step_1_foldfinal_<label>.joblib payload. An unmodified BundleLoader reads it through the no-trace index path and predicts by loading that single refit artifact and calling model.predict(X) directly — so the bundle reload-predict reproduces model.predict exactly. Directory-backed host estimators add individually hashed host_artifacts/ files to the manifest and ZIP; older inline joblib archives remain readable.

Parameters:
  • model – A predict-capable object (predict(X) -> np.ndarray). Must be joblib-serializable and importable by its module path at load time (e.g. a module-level wrapper class).

  • output_path – Destination bundle path; a .n4a suffix is enforced.

  • model_label – Human-readable model name used only for the manifest/pipeline label and the artifact filename. The loader keys on the step index, not this label, so it is cosmetic (sanitized to [A-Za-z0-9_]).

  • pipeline_uid – Optional source-run identifier recorded in the manifest.

  • preprocessing_chain – Optional preprocessing-chain summary string for the manifest.

  • provenance – Optional ADDITIVE manifest fields recording the export origin (e.g. the dag-ml run / plan / variant ids and an export_path marker). Older loaders ignore unknown manifest keys (BundleMetadata.from_dict()), so this never breaks bundle reads.

  • extra_members – Optional additional named ZIP members supplied by the caller. Names must be plain root-level files distinct from the bundle’s standard members.

  • train_steps – Optional REPLAYABLE training pipeline steps (the JSON-serialized form produced by serialize_component(), one entry per original run step). When given they are written as an ADDITIVE train_pipeline.json member so retrain(mode="full") can re-train the ORIGINAL pipeline structure from scratch. The predict path is untouched: pipeline.json keeps the single cosmetic model step the loader keys on, and older loaders ignore the extra member. Without it the bundle stays predict-only (its pipeline.json model label is cosmetic, not an importable component reference).

  • compress – ZIP_DEFLATED when True (default), else ZIP_STORED.

Returns:

The written bundle path (with the enforced .n4a suffix).