grus
A meaning-only pedigree IR (protobuf), a deterministic renderer that draws it as a Bennett/NSGC-standard SVG pedigree, and importers from the pedigree file formats people already have. Python 3.13, MIT.
uv add grus # or: pip install grus
grus import family.fam -o family.pbtxt # PLINK/LINKAGE PED, kinship2 tables, Phenopackets Family, Open Pedigree JSON
grus validate family.pbtxt
grus render family.pbtxt -o family.svg # --png with the `raster` extra (needs libcairo)
from grus import convert, ir, render
ps = convert.import_file("family.fam") # -> PedigreeSet, validated
svg = render.render_set_svg(ps) # one SVG for the figure; render.render_svg for one pedigree
text = ir.dump_set_pbtxt(ps) # canonical, diffable text form
What the IR is
Who is in the pedigree, their gender and clinical status, and how they relate — never coordinates. Identity is
Position{generation, index} (the drawn "II-3"); relationships are Mating{partner_a?, partner_b?, offspring[]} so
single parents, founder sibships, consanguinity, separated couples and childlessness are first-class; clinical status is
a per-condition list (affected / carrier / presymptomatic, with inheritance and onset when stated); twins, adoption,
donor parentage, pregnancy outcomes and collapsed sibships live where the standard draws them. The schema covers the
whole Bennett 2008 + 2022 vocabulary and evolves additively. Contract:
schema/proto/grus/models/pedigree.proto; rationale and the assessment of
Phenopackets / GA4GH Pedigree as alternatives: docs/design/ir.md.
What the renderer does
Ranks generations, orders each row to minimise crossings while keeping couples adjacent and sibships contiguous, solves
x on a constraint model, and draws standard symbols and connectors — deterministically, so the same IR always yields the
same bytes. Consanguineous loops, multiple mates and cross-lineage marriages route as edges rather than failing; the few
shapes it still cannot draw raise DeferredFeatureError instead of drawing something wrong.
docs/design/renderer.md, docs/design/layout-v2.md.
Importers
grus.convert reads PLINK .fam/.ped/.psam and LINKAGE .pre, kinship2/Pedixplorer tables (with the relation
matrix), GA4GH Phenopackets v2 Family JSON, and Open Pedigree / PhenoTips simple JSON. Generation and index are
synthesised (no data format carries them), the source id is kept in external_id, and nothing is inferred that the
source did not state. Per-format mapping tables: docs/design/convert.md.
Where it comes from
grus is built at the Centre for Population Genomics to round-trip pedigree figures in papers: figure → IR (a vision
model) → figure′ (this renderer), judged for semantic equivalence. That programme — the extraction prompt, corpus
mining, evaluation harness and review UI — is not part of this package; the IR and renderer are its stable core.
docs/PRODUCT.md; terms in GLOSSARY.md. Docs and docstrings here occasionally cite
design notes that stay in the private tree (architecture.md, eval.md, corpus.md, docs/plans/); those pointers
are provenance, not links.
Developing
uv sync, then uv run pytest, uv run --group lint pyright, pre-commit install. CI runs the same gates
(.github/workflows/): pre-commit, pytest (with and without the raster extra), stub freshness, and buf breaking
against the base branch. Protos are the source of truth; after editing one, buf lint,
buf breaking --against .git#branch=main, and uv run --group codegen python -m tools.schema.regen (needs buf).
Metadata
Release files for grus 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| grus-0.1.0.tar.gz | 199.4 kB | With provenance | Details for grus-0.1.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| grus-0.1.0-py3-none-any.whl | Python 3 | none | any | Details for grus-0.1.0-py3-none-any.whl |
Total release size: 303.0 kB
Release files / grus-0.1.0.tar.gz
| Download URL | grus-0.1.0.tar.gz |
|---|---|
| Size | 199.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
15424f17507f16ccfa9a6504d83280e298976109d89aefefd26c09c084f78659
|
|
BLAKE2b-256 checksum How to use checksums |
19191b4dda4ce92ec558e8c52a3abfc0ba4297e9f913b44a0514cf4f2b05dda2
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 13, 2026.
Transparency logRelease files / grus-0.1.0-py3-none-any.whl
| Download URL | grus-0.1.0-py3-none-any.whl |
|---|---|
| Size | 103.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
e7e91ade4d6c250e84bbd9e0235d69b8482383d2f279f4c0c99c2cf8bbef5fd8
|
|
BLAKE2b-256 checksum How to use checksums |
d4dc7fd477752b09e28b2217f88f88e1b34f3a77ccff6e736f522d77f426dedc
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 13, 2026.
Transparency logSecurity for grus 0.1.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for grus-0.1.0.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 13, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.