Skip to main content

nirs4all-providers

A dependency-light, soft-importing client layer over the nirs4all ecosystem's optional dataset catalogue and pipeline repository.

This package owns no NIRS, ML, IO, or parsing logic. Each adapter is a thin, uniform client over one sibling repo's real public API, exposed behind a single ProviderPlugin contract and discovered through soft-import. When a backing extra is not installed, the provider degrades to health().available == False instead of failing at import time. Providers are not controllers and never execute ML or write back to the ecosystem.

This is not a second full Python implementation of nirs4all. The runtime packages published as nirs4all in Rust, JavaScript/WASM, R, and MATLAB/Octave should keep consuming nirs4all-core / nirs4all-methods for portable logic, and use these neutral provider contracts only when they need dataset or repository read access.

Scope: read slice. Publish/upload, benchmark arenas, and paper export/publishing stay outside this package. to_dataset_package is present only as a soft, transparent bridge to nirs4all-io, forwarding to the io entrypoint verbatim and returning a typed availability/refusal when the optional io bridge is absent or too old.

nirs4all-benchmarks and nirs4all-papers remain in their owning repositories. They are not provider facets, extras, conformance targets, or release-gate siblings of this package.

Install

Install the published provider client package from PyPI:

python -m pip install nirs4all-providers                # base: contracts + registry only (pure stdlib)
python -m pip install "nirs4all-providers[datasets]"   # + nirs4all-datasets
python -m pip install "nirs4all-providers[repository]" # + nirs4all-repository
python -m pip install "nirs4all-providers[io]"         # + optional nirs4all-io package bridge
python -m pip install "nirs4all-providers[all]"        # datasets + repository + io

For local development from a source checkout:

git clone https://github.com/GBeurier/nirs4all-providers.git
cd nirs4all-providers
python -m pip install .              # base: contracts + registry only (pure stdlib)
python -m pip install ".[datasets]"  # + nirs4all-datasets
python -m pip install ".[repository]" # + nirs4all-repository
python -m pip install ".[io]"        # + optional nirs4all-io package bridge
python -m pip install ".[all]"       # datasets + repository + io

Each backing is optional and soft-imported; install only what you consume. The base install depends on nothing but the standard library. .[all] installs the provider backings; bridge extras owned by backing projects stay explicit, for example nirs4all-datasets[nirs4all] for DatasetProvider.to_spectro_dataset().

Use

import nirs4all_providers as providers

providers.provider_ids()        # ('datasets', 'repository')
providers.available_providers() # the subset whose extra is installed

# Health never raises, even when the extra is absent:
providers.provider_health("datasets")
# Health(provider_id='datasets', available=True, reachable=True, version='0.3.5', detail=None)

# Get a typed adapter (raises ProviderUnavailable with a clear pip hint if the extra is missing):
datasets = providers.get_provider("datasets", root="/path/to/catalogue")
datasets.list_datasets(tier="public")        # -> list[card-dict]
datasets.card("some_id")                     # -> card dict | None
ds = datasets.get_dataset("some_id")         # -> NirsDataset (needs nirs4all-datasets)
datasets.retrieve_dataset("some_id")         # -> retrieval status dict; local cache only
sd = datasets.to_spectro_dataset("some_id")  # -> nirs4all SpectroDataset (needs nirs4all-datasets[nirs4all])

The two providers (read surface)

Provider provider_id Backing Read methods Writes
DatasetProvider datasets nirs4all-datasets list_datasets · card · get_dataset · retrieve_dataset · to_spectro_dataset · to_dataset_package · describe_dataset_package local cache (via get() / retrieve())
PipelineProvider repository nirs4all-repository get_pipeline_list · card · get_pipeline · get_bundle · verify none

Every adapter also exposes the contract trio: provider_id, version(), health(), capabilities().

Lookup methods validate their identifiers before delegating. Use dataset ids with DatasetProvider methods, repository pipeline ids from PipelineProvider.get_pipeline_list() rows with repository get_pipeline().

Benchmarks are consumed through nirs4all-benchmarks itself, where Arena stores, score ledgers, and planning/runner workflows belong. Paper bundles and reproducibility sidecars are consumed through nirs4all-papers itself. This package deliberately exposes no shims, fallbacks, or public provider ids for either domain.

Contract

  • ProviderPlugin — the structural protocol (provider_id, version(), health(), capabilities()). Adapters are duck-typed against it; they need not subclass it.
  • Health{available, reachable, version, detail}. available is import-availability; reachable is an optional network-free deeper probe (None when not performed).
  • Capabilities{serves, executes, writes, portability}. Provider-level and distinct from the operator-level ControllerCapability (LOCK-CAP); the portability field only references CAP-002/CAP-004 for served artifacts.
  • WriteAccessnone / local-cache / gated. The read slice never reaches gated.

Neutral contracts (multi-language)

This Python package is one conformant client of a language-neutral provider contract — not the definition of it. The read slice (datasets · repository) is fundamentally a set of static content artifacts (a catalogue index, identity cards, per-file SHA-256 fetch manifests, descriptors, recipes) served over HTTPS/DOI and integrity-verified. None of that requires Python, so R / JS-WASM / Rust clients reach the same data by porting the schemas + a thin fetcher, never by depending on this package.

Those non-Python clients are expected to plug the fetched descriptors into their own target-language nirs4all packages and nirs4all-methods bindings. The architecture is: provider contracts travel across languages; runtime logic still lives in core/methods, not in a Python shim exported from here.

The five schemas are frozen in the ecosystem repo (nirs4all-ecosystem/docs/contracts/providers/) and mirrored byte-identically here under src/nirs4all_providers/contracts/:

Schema Governs Behind
provider_descriptor.v1 neutral {provider_id, version, health, capabilities} a client emits provider_id/version()/health()/capabilities()
dataset_card.v2 dataset identity/metadata card DatasetProvider.card / list_datasets
dataset_manifest.v2 per-file SHA-256 fetch manifest dataset byte acquisition
repository_index.v1 pipeline catalogue index PipelineProvider.get_pipeline_list
pipeline_descriptor.v1 pipeline descriptor/card PipelineProvider.card
import nirs4all_providers as providers

# Emit the neutral descriptor for every registered provider (no backing extra required):
providers.all_provider_descriptors()          # -> [ {schema_version, provider_id, version, health, capabilities}, ... ]
providers.provider_descriptor(providers.get_provider("datasets"))  # -> the same shape for one live adapter

# Load / validate against the vendored schemas (pure-stdlib subset validator, no third-party dep):
schema = providers.load_contract_schema("dataset_card.v2")
providers.iter_contract_errors(providers.load_contract_fixture("dataset_card.example"), schema)  # -> [] when valid

For datasets specifically, the non-Python provider is the nirs4all-datasets acquisition contract: catalog/index.json is served/bundled as JSON, n4ds_resolve returns the tier-sanitized descriptor plus the SHA-256-pinned file list, and R/WASM/Rust hosts fetch/verify those files and read canonical Parquet with native tooling. This package may emit a Python provider_descriptor.v1, but R/WASM/Rust do not link to nirs4all_providers to consume datasets.

The R and WASM story is explicit in the ecosystem docs/contracts/providers/README.md: port the schemas and a thin HTTP-GET + SHA-256-verify fetcher over these contracts. Where a language client does not yet exist, the deliverable is the neutral contract plus a gate (GATE-PROV-R, GATE-PROV-WASM, GATE-PROV-NATIVE) — never a Python shim, and never a new dependency on this package.

Contract gate: PYTHONPATH=src python scripts/validate_contracts.py --canonical ../nirs4all-ecosystem/docs/contracts/providers. The CI/release gate requires this canonical byte-identity check; set NIRS4ALL_PROVIDERS_CANONICAL_CONTRACTS only when the ecosystem checkout lives somewhere else.

Boundaries

  • The provider layer is net-new glue only; each backing repo keeps its own package + API and stays the single source of truth for its domain.
  • Not a dependency of nirs4all-core / dag-ml / nirs4all-io. Consumers depend on the contract (the schemas / served artifacts) and may optionally use this Python client; the arrow never points into those packages from here.
  • The target-language packages named nirs4all consume nirs4all-core and nirs4all-methods; they do not consume this package as a runtime substitute or duplicate its read-client glue in the wrong layer.
  • No adapter re-implements nirs4all / nirs4all-io / nirs4all-methods. nirs4all-io remains the dataset-assembly owner; package methods delegate to nirs4all-io and do not assemble packages here.
  • No network calls originate in this layer, and no ecosystem write-back is performed.
  • nirs4all-drafts / nirs4all-lab are private and out of scope.

Develop

python scripts/ci_gate.py  # version-sync + ruff + mypy + tests + conformance + neutral contracts
ruff check .       # lint
mypy src           # types
pytest -q          # tests (hermetic: fakes, no network, no real backing required)

Release Gate

nirs4all-providers-release-gate
# or
python -m nirs4all_providers.release_gate --json

Release publication also runs the version-sync guard:

nirs4all-providers-version-sync
# explicit release/tag check
nirs4all-providers-version-sync --expected-tag v0.2.8 --json

The canonical version is src/nirs4all_providers/__init__.py::__version__; the expected release tag is v{__version__}. Branch CI and local non-release runs pass without a tag, while GitHub release/tag contexts or NIRS4ALL_PROVIDERS_EXPECTED_TAG must match exactly.

This gate is intentionally stricter than the hermetic unit suite. It fails when a registered backing extra is absent and reports the exact install hint, so a release environment cannot get a false green from skipped sibling conformance. It also fails if any provider advertises execution through Capabilities.executes or an execution-like served method. The only allowed boundary is serving dataset/repository metadata and config; runtime execution, benchmark proof, and paper export stay with their owning packages.

For a local nirs4all workspace, use the sibling harness:

python -m nirs4all_providers.local_release_gate --workspace-root /path/to/nirs4all --json
# or
nirs4all-providers-local-release-gate --workspace-root /path/to/nirs4all
# optionally add an existing dependency venv/site-packages/PYTHONPATH directory
python -m nirs4all_providers.local_release_gate --workspace-root /path/to/nirs4all --dependency-path /path/to/.venv

The harness verifies that nirs4all-datasets and nirs4all-repository each expose a real src/<module>/__init__.py, prepends those source paths, then runs the same strict release gate. Existing dependency paths may be supplied with repeated --dependency-path flags or NIRS4ALL_PROVIDERS_LOCAL_DEPENDENCY_PATHS (using the platform path separator); venv roots are resolved to their site-packages directories. It does not install dependencies or fake missing packages; missing sibling trees, non-package layouts, or import-time dependency blockers remain release-gate failures, with the missing transitive module and matching sibling requirement reported when available.

Brand

Logo assets live in assets/brand/icon.svg plus stacked.svg / stacked-dark.svg, using the shared ecosystem mark (spectral wave, white content) recolored to this package's key. The key is magenta #D946EF with the n4v lettermark; v keeps the mark distinct from nirs4all-papers (n4p), which already owns the p initial. The raster/wordmark kit is generated by the nirs4all-org pipeline and mirrored here, not hand-authored. See assets/brand/README.md for the rationale.

License

Dual-licensed CeCILL-2.1 OR AGPL-3.0-or-later, consistent with the nirs4all ecosystem policy. See LICENSE, LICENSING.md, and the full texts under LICENSES/.

Community

Download files

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

Source Distribution

nirs4all_providers-0.2.10.tar.gz (65.3 kB view details)

Uploaded Source

Built Distribution

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

nirs4all_providers-0.2.10-py3-none-any.whl (61.5 kB view details)

Uploaded Python 3

File details

Details for the file nirs4all_providers-0.2.10.tar.gz.

File metadata

  • Download URL: nirs4all_providers-0.2.10.tar.gz
  • Upload date:
  • Size: 65.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for nirs4all_providers-0.2.10.tar.gz
Algorithm Hash digest
SHA256 347f779632cdb0b7e8c217f794b1154f2324f3ccd494aba63009427382c9f556
MD5 fb59d3c31de1b714678dadba3cff2a14
BLAKE2b-256 edb42998bc3f91e59f3d9c6e16f9281167f094ed90da671342eafdd8e23e3fc8

See more details on using hashes here.

Provenance

The following attestation bundles were made for nirs4all_providers-0.2.10.tar.gz:

Publisher: publish.yml on GBeurier/nirs4all-providers

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_providers-0.2.10-py3-none-any.whl.

File metadata

File hashes

Hashes for nirs4all_providers-0.2.10-py3-none-any.whl
Algorithm Hash digest
SHA256 6cab02c6b87853c90e5a5d2b0d8b3436a72967bdd4d76d78bf548356254ca89d
MD5 20bd850c5515faf94fc9a5d66691247b
BLAKE2b-256 cc53bc15a95a2c523a460fd8918268f7767ee2997bbed5da49ddb09a98ce916f

See more details on using hashes here.

Provenance

The following attestation bundles were made for nirs4all_providers-0.2.10-py3-none-any.whl:

Publisher: publish.yml on GBeurier/nirs4all-providers

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

Release history Release notifications | RSS feed

This release

0.2.10 This release

2 files

0.2.9

2 files

0.2.8

2 files

0.2.7

2 files

Supported by

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