Versioning & compatibility
snipe is built from a single workspace and shipped two ways — a Rust library and a Python package with a Typer CLI. To keep the two halves consistent, snipe pins one version string and uses one signature format. This page describes both, and exactly what snipe can read versus what it will write.
One version, single-sourced
Section titled “One version, single-sourced”The current version is 1.0.0-dev. It lives in exactly one place — Cargo.toml’s [package].version — and everything else reads from there. The Python package declares its version dynamic so the build reads it back out of Cargo.toml rather than duplicating it, and the CLI’s snipe.cli._VERSION, pyproject.toml, and pixi.toml are all held to the same value.
That agreement isn’t a convention you have to remember — it’s enforced. A dedicated parity test (tests/test_cli_parity.py) fails the build if any of those strings drift out of lockstep, so a mismatched version can’t ship.
One signature format: .snipesig
Section titled “One signature format: .snipesig”snipe has exactly one native signature format: .snipesig. Internally it is Parquet-encoded — edgemer columns stored in compressed row-groups, with the full signature header (every field, including options like --keep-acgt) carried as a JSON blob in the Parquet footer for full fidelity.
The important framing: Parquet is the encoding, not a new extension. There is no separate .parquet file type. .snipesig remained the format when its encoding changed from JSON-gzip to Parquet — same name, new internals.
What snipe writes
Section titled “What snipe writes”Writes are always Parquet and always single-signature. There is no toggle for this — JSON writing was removed entirely, so there is no legacy-JSON write hatch and no multi-signature output.
A few commands specialize this shape:
sketch --genomestores its per-chromosome data in one Parquet.snipesigusing coordinate columns, keeping the whole genome in a single file.downscaleandexportoperate on a single signature and will error if handed a legacy multi-signature JSON input.
Sourmash .sig and TSV are secondary export targets; a sourmash export carries only the K1 layer — the edgemer (K2) information does not cross that boundary. See sourmash interoperability →.
What snipe reads
Section titled “What snipe reads”snipe reads more than it writes, on purpose. The legacy JSON-gzip .snipesig encoding is read-only backward-compat — retained so pre-Parquet files still open, but never produced.
Loading auto-detects the encoding from the file’s opening bytes, so you never have to declare which kind you have:
PAR1at the start → a Parquet.snipesig(the current encoding).1f 8b(gzip) or[→ a legacy JSON.snipesig.
The loader dispatches on those magic bytes automatically. Old files keep opening; new files are always Parquet.
The library-only build is narrower
Section titled “The library-only build is narrower”Parquet support rides on the sketch-parquet feature, which is on by default and pulled into every normal wheel — so any ordinary install reads and writes Parquet .snipesig.
A stripped library-only build (cargo build --no-default-features) leaves that feature out and stays Parquet-free. It can still read and write the legacy JSON .snipesig, but it will error on a Parquet one. This is the one configuration where “what snipe can read” narrows — worth knowing if you embed the core library without the default features.
- The
.snipesigformat → — how edgemers are stored, reproducibly. - Edgemers → — the K-mer pair that
.snipesigpreserves with full fidelity. - sourmash interoperability → — what an export carries.