SHELL — SHELL Highlights Epithelium and Lumen Locations
A whole-slide image segmentation pipeline for H&E-stained histopathology. SHELL uses Macenko colour deconvolution and a SegResNetVAE to segment epithelium and lumen/stroma regions.
The ONNX inference model is bundled with the package. The repository-only PTH checkpoint is used only when exporting a new ONNX bundle.
Label Map
| Value | Label |
|---|---|
| 0 | Background / White |
| 1 | Epithelium |
| 2 | Stroma |
| 8 | Edge epithelium (WSI mode only) |
Quick Start
Installation
pip install shell
Python 3.10 – 3.12 is required (constrained by the OMERO dependency).
To use OMERO support (fetching images from an OMERO server):
pip install shell[omero]
CLI — Local WSI Inference
The bundled model is used automatically — no --model-path needed:
shell infer --input slide.tiff --output prediction.tiff
To use a specific bundled model version:
shell infer --input slide.tiff --output prediction.tiff --model-version v1
To use a custom ONNX model instead:
shell infer --input slide.tiff --output prediction.tiff --model-path /path/to/custom.onnx
CLI — OMERO Inference
shell infer-omero \
--host $OMERO_SERVER --port $OMERO_PORT \
--username $OMERO_USERNAME --password $OMERO_PASSWORD \
--image-id 12345 \
--output pred_12345.tiff
As a Library
from shell.infer_wsi import infer_wsi
# Uses the bundled latest model automatically
label_map = infer_wsi(
input_path="slide.tiff",
output_path="prediction.tiff",
)
You can also load the model directly:
from shell.model import build_model
# Bundled latest
model = build_model(device="cuda")
# Specific bundled version
model = build_model(model_version="v1", device="cuda")
# Custom ONNX model
model = build_model("/path/to/custom.onnx", device="cuda")
Model Versioning
ONNX models live in src/shell/weights/ and are registered in
shell.model.MODEL_REGISTRY. The LATEST_MODEL constant controls which
version is loaded by default.
| Version | File | Notes |
|---|---|---|
v1 |
model_v1.onnx |
Initial release — SegResNetVAE trained on H&E |
Adding a New Model
- Keep the source
.pthcheckpoint in the repository and export it withscripts/export_onnx.py. - Add an entry to
MODEL_REGISTRYinsrc/shell/model.py:MODEL_REGISTRY: dict[str, str] = { "v1": "model_v1.onnx", "v2": "model_v2.onnx", # new }
- Update
LATEST_MODEL:LATEST_MODEL: str = "v2"
- Bump the package version and release.
Development Setup
Prerequisites: Python 3.10–3.12 and Hatch.
git clone https://github.com/laviolette-lab/shell.git
cd shell
pip install hatch
Optionally install pre-commit hooks:
pip install pre-commit
pre-commit install
Common Commands
| Task | Command |
|---|---|
| Run tests | hatch run test:test |
| Tests + coverage | hatch run test:cov |
| Lint | hatch run lint:check |
| Format | hatch run lint:format |
| Auto-fix lint | hatch run lint:fix |
| Format + fix + lint | hatch run lint:all |
| Type check | hatch run types:check |
| Build docs | hatch run docs:build-docs |
| Serve docs | hatch run docs:serve-docs |
| Build wheel | hatch build |
| Clean artifacts | make clean |
Publishing
Releases are fully automated. Creating a GitHub Release triggers the
publish.yml workflow, which:
- Builds a wheel and sdist and publishes them to PyPI via trusted publishing (OIDC — no API tokens needed).
- Builds standalone binaries for Linux (x86_64) and macOS (x86_64 + arm64) using Nuitka with Python 3.12.
- Uploads the binaries as release assets on the GitHub Release.
How to Release
# 1. Bump the version in src/shell/__about__.py
# 2. Commit and tag
git add -A
git commit -m "release: v0.2.0"
git tag v0.2.0
git push && git push --tags
# 3. Create a GitHub Release from the tag
gh release create v0.2.0 --generate-notes
One-Time Setup (PyPI)
- Go to https://pypi.org/manage/account/publishing/.
- Add a pending publisher:
- PyPI project name:
shell - Owner:
laviolette-lab - Repository:
shell - Workflow name:
publish.yml - Environment name:
pypi
- PyPI project name:
One-Time Setup (GitHub)
- In repository Settings → Environments, create an environment named
pypi(optionally with manual approval protection).
Project Structure
shell/
├── src/
│ └── shell/ # Package source
│ ├── __init__.py # Public API & version export
│ ├── __about__.py # Version string
│ ├── cli.py # CLI entry point
│ ├── model.py # ONNX model helpers & registry
│ ├── preprocessing.py # Macenko deconvolution & EHO transform
│ ├── inference.py # Sliding-window inference
│ ├── infer_wsi.py # Local WSI pipeline
│ ├── infer_omero_wsi.py # OMERO WSI pipeline (tiled, pipelined)
│ ├── weights/ # Bundled model weight files
│ │ └── model_v1.onnx
│ └── py.typed # PEP 561 marker
├── tests/ # pytest test suite
├── docs/ # MkDocs source files
├── .github/
│ └── workflows/
│ ├── build.yml # CI: build wheel on push/PR
│ ├── pytest.yml # CI: run tests
│ ├── lint.yml # CI: ruff lint + format check
│ └── publish.yml # CD: PyPI publish + Nuitka binaries
├── pyproject.toml # All project & tool configuration
├── Dockerfile # Multi-stage build (hatch / dev / prod)
├── Makefile # Dev shortcuts
└── README.md
Contributing
See CONTRIBUTING.md for development guidelines.
License
shell is distributed under the terms of the MIT license.
Metadata
Release files for lavlab-shell 0.9.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| lavlab_shell-0.9.1.tar.gz | 37.1 MB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| lavlab_shell-0.9.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 43.0 MB
Release files / lavlab_shell-0.9.1.tar.gz
| Download URL | lavlab_shell-0.9.1.tar.gz |
|---|---|
| Size | 37.1 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
c6c855b654ec3ecbf83bab221aa45ba7dac08993c0001c0f7185604a7bc87223
|
|
BLAKE2b-256 checksum How to use checksums |
276b303b929185097d2f9c287177824e5f371c1e516c70162ed66f2006aaaec4
|
| 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 Oct 13, 2026.
Transparency logRelease files / lavlab_shell-0.9.1-py3-none-any.whl
| Download URL | lavlab_shell-0.9.1-py3-none-any.whl |
|---|---|
| Size | 5.9 MB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
fdb2acb832afccfebe908a2a04d0d081081b96b9fa07e3a416f708fbaff1a417
|
|
BLAKE2b-256 checksum How to use checksums |
a0c778b38dda8e4630fa18efb1162a2a55ca2e70af1403a2f64a17269f96ae9c
|
| 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 Oct 13, 2026.
Transparency log