This release is a pre-release and may not be stable for production use.
sleap-roots-contracts
Shared result + provenance contract for the sleap-roots ↔ Bloom pipeline.
This is a small, dependency-light library — code-agnostic toward Bloom (no Bloom import; no DB
or network I/O, and no ambient filesystem reads in the contract-model surface — the exceptions
are deliberate and named: emit_schema writes the JSON Schema artifacts, registry/examples
read packaged resources, and read_run_manifest reads one named file from a caller-supplied
directory) — that defines the shape of a per-scan pipeline result and its provenance (Pydantic
v2 models), emits a versioned JSON Schema artifact, and ships a trait-definitions registry. The
Python producers (sleap-roots-predict, sleap-roots-traits) import it; Bloom consumes the
emitted schema.
It also defines the analysis-input contract — the canonical shape of the wide trait
table that crosses the sleap-roots-analyze ↔ Bloom boundary.
validate_analysis_input(df, *, strict=False) structurally validates that table against
fixed canonical role names (genotype + optional sample_id / replicate /
image_path) plus an open set of opaque numeric trait columns, returning a structured
ValidationResult. It operates on a pandas DataFrame, so pandas is an optional install
extra — pip install sleap-roots-contracts[pandas] — while the runtime core stays
pydantic + pyyaml. Canonical example tables ship in the package
(sleap_roots_contracts.examples.load_analysis_input_example(...)) so consumers can load a
validating frame straight from the released wheel.
It also defines the model-selection contract — ModelCard and Selector, the Python-side
shape shared by sleap-roots-training (which writes a production model's selection metadata as
wandb artifact metadata at promotion) and sleap-roots-predict (which reads cards to choose a
model per root type and calls to_model_ref(runtime_sleap_nn_version)). Since 0.1.0a8 one card
describes one physical model: it carries a scalar root_type plus a non-empty selectors
list, where each Selector is one whole validated (species, mode, age_min, age_max) context the
model was approved for. A card matches when some single selector matches all of species, mode
and age — never the cross product, so a generalist model cannot advertise a combination nobody
trained, and an age must be compared against a matching selector's window rather than any
card-level bound. root_type stays scalar because it is intrinsic to the weights. Selector.mode
and ModelCard.root_type are the controlled Mode and RootType vocabularies, matched exactly.
Unlike the result and analysis-input contracts above, it is a producer↔producer contract that
never crosses the Bloom boundary, so it is not emitted to the JSON Schema.
Since 0.1.0a6 it also defines the label-selection contract — LabelCard, the Python-side
label-provenance shape written by the /build-labeling-package workflow (which already computes
this metadata and discarded it at publish) and read by training/lineage tooling to answer "where
did these labels come from?". Like ModelCard, it is a producer↔producer contract and is not
emitted to the JSON Schema.
The contract-owned Mode = {cylinder, multiplant cylinder, plate} vocabulary types the mode
field on both registries' cards — Selector.mode on the model side, LabelCard.mode on the
label side — making it the single source of truth that closes the cylinder/cyl split between
them. Consumers needing the value set for a manual
membership check use typing.get_args(Mode) rather than re-declaring it.
Since 0.1.0a5 it also defines the prediction-manifest contract — PredictionArtifact/
PredictionManifest, the Python-side shape of predict's per-scan .slp output, written by
sleap-roots-predict and read by bloomctl to construct cyl_scan_intermediates blob bytes.
Like ModelCard, it is a producer↔producer contract and is not emitted to the JSON Schema.
Since 0.1.0a7 it also defines the run-manifest contract — RunManifest/
RUN_MANIFEST_FILENAME, the run-scoping shape written by bloomctl and read by
sleap-roots-predict/sleap-roots-traits to scope processing to exactly the scan_keys a run
was given. Like ModelCard, it is a producer↔producer contract and is not emitted to the
JSON Schema. Since 0.1.0a9 it also defines the per-run filename convention and the shared
resolution policy — run_manifest_filename, pipeline_run_id_from_env,
run_manifest_name_for_writing, read_run_manifest, check_run_manifest_identity, and
load_run_manifest (the recommended entry point, composing the three read/parse/check
primitives in one call; LoadedRunManifest is its result) — so the four consumer call sites
agree on one definition rather than three (talmolab/sleap-roots-pipeline#71). Adopters must
bump readers before the writer: once a writer
publishes run_manifest.<pipeline_run_id>.json, an un-adopted reader no longer finds
run_manifest.json and falls back to its own whole-tree discovery, which is worse than the
shared-manifest defect this release fixes.
Since 0.1.0a4 it also ships the param-resolution oracle —
resolve_params(metadata, overrides=None) -> ResolvedParams maps a single Bloom
cyl_scans_extended scan-metadata row to the {species, mode, age} params that select a
ModelCard. It is a pure producer-side function (not emitted to the JSON Schema), and it is
the single source of truth for that mapping: its resolved values feed param_hash →
idempotency_key, so a second copy in a consumer would silently break first-writer-wins
idempotency. sleap-roots-predict and bloomctl both import it. It reads Bloom's column names
(species_name, plant_age_days) as dict keys — a deliberate, documented soft coupling,
hoisted into the module constants SPECIES_NAME_FIELD / PLANT_AGE_DAYS_FIELD.
It is sub-project #1 of the sleap-roots ↔ Bloom integration program. Design and plan:
docs/01-contract-library-design.md and docs/02-contract-library-plan.md.
Develop
uv sync
uv run pytest -v
uv run black --check src tests && uv run ruff check src tests
Key ideas
- Pydantic is canonical;
schema/*.jsonis generated and drift-guarded in CI. - Trait values are long-format rows (no jsonb); provenance is a jsonb blob on the source.
- Hashes (
param_hash,idempotency_key) are producer-side only; Bloom treats them as opaque strings. - Distributed via PyPI (no Docker image — this is a library).
Metadata
Release files for sleap-roots-contracts 0.1.0a9
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| sleap_roots_contracts-0.1.0a9.tar.gz | 39.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| sleap_roots_contracts-0.1.0a9-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 87.3 kB
Release files / sleap_roots_contracts-0.1.0a9.tar.gz
| Download URL | sleap_roots_contracts-0.1.0a9.tar.gz |
|---|---|
| Size | 39.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
f5000772dbcae47b32c6102edcd6944ac48e868cc58ef2f20d54a938d678cc78
|
|
BLAKE2b-256 checksum How to use checksums |
3143979996ec25aae067b371c49807c6ab1815936450abfd32aa93285ed1abd7
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.12.17 {"installer":{"name":"uv","version":"0.12.17","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / sleap_roots_contracts-0.1.0a9-py3-none-any.whl
| Download URL | sleap_roots_contracts-0.1.0a9-py3-none-any.whl |
|---|---|
| Size | 47.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
369b1e92e276f508b5072b809ebf5c602056af8f8f7f1e8dc3833deb472caa65
|
|
BLAKE2b-256 checksum How to use checksums |
fa1e0aad4d123dc02b14f828476cd919ed21a3fd3352b5ad5cb5a62267f88174
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.12.17 {"installer":{"name":"uv","version":"0.12.17","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|