Contributing to pardesline¶
Thank you for considering a contribution. The easiest and most useful ones are a dataset manifest, an algorithm, a model manifest and an example; each has a template and a checklist below. The rules exist to keep the package trustworthy for people who run it on data that matters.
Ten-minute setup¶
git clone https://github.com/pardesline/pardesline
cd pardesline
python -m venv .venv && . .venv/bin/activate # Windows: .venv\Scripts\activate
pip install -e ".[all,dev]" # Python 3.10-3.13 (Open3D 0.20) or 3.10-3.12 (0.19)
pre-commit install # ruff on every commit (optional, CI runs it anyway)
pytest -q -m "not local and not medical" # core tests, about a minute
pytest -q # everything, about ten minutes
mkdocs serve # docs at http://127.0.0.1:8000 (pip install mkdocs-material "mkdocstrings[python]" mkdocs-gen-files)
ruff check . and ruff format . must pass; ruff format also formats the Python blocks inside Markdown files.
Pull request checklist¶
- [ ] One change per pull request, with a test.
- [ ]
ruff check .,ruff format --check .,pytest -q -m "not local and not medical"green locally. - [ ] No data in the repository: tests generate their inputs, examples download through
pl.load. - [ ] No silent guessing: when a format does not carry units, a frame or a label meaning, the code raises or asks.
- [ ] Every new parameter is in the catalog JSON with name, type, default, min, max, description, and in
src/pardesline/catalog/data/_defaults.jsonwith the reason for its default and the data it was validated on (tests/test_catalog.pyenforces both). - [ ] CLI contracts never change silently: every op under
pardesline.opsis callable aspython -m pardesline.ops.<module>.<script> --input … --output …; renaming or removing a flag is a breaking change with a CHANGELOG entry. - [ ] A line in
CHANGELOG.mdunder Unreleased. - [ ] Commit messages: imperative, prefixed
feat:,fix:,docs:,ci:,tests:,release:, body says what changed and what was verified.
Adding a dataset¶
Copy templates/new_dataset/ and follow its README. In short:
- Probe the source before writing anything: Hugging Face tree (
HfApi().list_repo_tree, scoped to a sub-folder, 1–2 s between calls), a zip or tar on S3 / Zenodo (RemoteZip/RemoteTarindex it by HTTP Range), a TCIA collection (getSeries), an S3 bucket, a URL index. Record the licence exactly as the source states it, with the date you checked. - Write the manifest
src/pardesline/data/manifests/<name>.json:source(scheme and location),roleswithtype,pattern({id}and other placeholders),frame,units,labels,layoutfor raw arrays,modality;license(spdx,commercial,redistribution,requires_agreement,note,source_url);citation,homepage,pairing,size_mb,tags. Never embed data; never guess what the files do not say. - Verify offline:
pytest -q tests/test_manifest.py tests/test_skills.py. - Verify live:
python -c "import pardesline as pl; ds = pl.load('<name>'); print(len(ds.ids)); print(ds[0].describe())"and fetch one small role. Compare the sample count with the source's own count. - Wire it in: the table in
docs/datasets.mdand thedatasets-and-manifestsskill,docs/_gen/datasets_table.pypicks it up for the README, the docs page is generated at build time. Add the name prefix totests/test_skills.pyif it is new.
What is not accepted: mirrored data, loaders that bypass a gate or a data-use agreement, licences copied from memory.
Adding an algorithm¶
Copy templates/new_algorithm/. In short:
- Script
src/pardesline/ops/<module>/<name>.py:argparsewith--input,--output(and--movingfor two-input methods), typed flags for every parameter, exit 0 on success, logs through loguru, a JSON next to the output when the method returns numbers (transforms, metrics). - Catalog entry in
src/pardesline/catalog/data/<module>.json: the method withid,name,script,output_extensionand every parameter (name,type,default,min,max,options,description,advanced). - Defaults rationale in
_defaults.json:validated_onfor the method and one sentence per parameter saying why the default is what it is and when to change it. Run the method on a bundled dataset and write what you measured; "generated test data" is an acceptable regime when that is the truth. - Tests: a smoke test in
tests/test_ops_smoke.pyon generated data;tests/test_catalog.pychecks the catalog and the script agree. - High-level call when it fits the object model (
align,segment,to_mesh,clean…):src/pardesline/object/__init__.py, with a docstring. - Docs: the algorithm page is generated; add a how-to page under
docs/how-to/if the method answers a question people search for, and an example underexamples/if it runs on a bundled dataset.
Adding a model manifest¶
The model registry (one-line access to pretrained models, the same pattern as datasets) is on the roadmap; model manifests can be contributed now so the runner has something to load when it lands. Copy templates/new_model/: a manifest.json (source, weights URI, licence, input type, task, memory and GPU needs, provenance, citation), a loader stub that says what it would download and how it would be called, and a docs page under docs/models/. List it on the Models wanted issue.
Reference scripts that read a pardesline dataset and run a model today (as the PointNet, JEPA, VAE and DINOv3 scripts do) go under the matching skill's scripts/ folder with a --smoke mode and are documented in the skill.
Adding an example¶
Copy templates/new_pipeline/: one folder under examples/, a run.py that loads a bundled dataset, runs one algorithm or model, writes one image and a JSON summary, and a README.md with the dataset, the licence, the runtime and what the defaults handled. Title it <algorithm or model> on <dataset>, run it, commit the image and the summary (large outputs are ignored by .gitignore), add a row to examples/README.md and a card to the README gallery.
Real industrial or medical cases go to examples/real_cases/ with the data or a loader for it, de-identified by you, under a licence that allows redistribution.
Adding a skill (expert guide)¶
skills/<name>/SKILL.md with front matter (name, description between 200 and 1 500 characters), the structure of the existing skills (idea, pipeline, parameters by name, metrics, failure modes, datasets to practise on), optional scripts/. tests/test_skills.py checks that every module.method, pl.<name> and dataset name you cite exists. The page under docs/guides/ or docs/models/ is generated.
Reporting a bug¶
Open an issue with the template: the snippet or command, the full log, pardesline version, and the versions of Open3D, PyVista and SimpleITK if relevant. Security issues: see SECURITY.md.
Release process (maintainers)¶
- Reproduce the CI locally in a clean venv (
ruff, core tests on the newest Python). - Bump
src/pardesline/_version.py,.claude-plugin/plugin.json,.claude-plugin/marketplace.json; date the CHANGELOG section and its compare links; update the README status line. - Commit
release: X.Y.Z, tagvX.Y.Z, push both. - Publish a GitHub release from the tag: the
publish.ymlworkflow uploads to PyPI through Trusted Publishing and thedocs.ymlworkflow deploys the versioned documentation. - Verify
pip install pardesline==X.Y.Zin a fresh venv.
Licence¶
By contributing you agree that your contribution is licensed under the Apache License 2.0, like the rest of the project. Datasets you describe keep their own licences, which your manifest must state as the source states them.