SHELL Highlights Epithelium and Lumen Locations — whole-slide H&E segmentation
Project description
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.
Model weights are bundled with the package — no separate download required.
Label Map
| Value | Label |
|---|---|
| 0 | Background / White |
| 1 | Epithelium |
| 2 | Stroma |
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 your own weights instead:
shell infer --input slide.tiff --output prediction.tiff --model-path /path/to/custom.pth
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 weights file
model = build_model("/path/to/custom.pth", device="cuda")
Model Versioning
Model weights 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.pth |
Initial release — SegResNetVAE trained on H&E |
Adding a New Model
- Place the new
.pthfile insrc/shell/weights/. - Add an entry to
MODEL_REGISTRYinsrc/shell/model.py:MODEL_REGISTRY: dict[str, str] = { "v1": "model_v1.pth", "v2": "model_v2.pth", # 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 # SegResNetVAE 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.pth
│ └── 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.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file lavlab_shell-0.4.0.tar.gz.
File metadata
- Download URL: lavlab_shell-0.4.0.tar.gz
- Upload date:
- Size: 24.2 MB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e8979ce0997c97c4933123f1bc323cc70f8d15137c15d9f2e6d16586cfd76d8a
|
|
| MD5 |
058527c23ddeacada48dbdc7c10febb8
|
|
| BLAKE2b-256 |
a7148a6515e6240d60e75c64f2f5cbd2b21bdf9c73d6ffe6153bcd6cbdbc38f6
|
Provenance
The following attestation bundles were made for lavlab_shell-0.4.0.tar.gz:
Publisher:
publish.yml on laviolette-lab/shell
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
lavlab_shell-0.4.0.tar.gz -
Subject digest:
e8979ce0997c97c4933123f1bc323cc70f8d15137c15d9f2e6d16586cfd76d8a - Sigstore transparency entry: 1018255091
- Sigstore integration time:
-
Permalink:
laviolette-lab/shell@80f4b400fc5f0ef054431f3462925943f3ea40dc -
Branch / Tag:
refs/tags/v0.4.0 - Owner: https://github.com/laviolette-lab
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@80f4b400fc5f0ef054431f3462925943f3ea40dc -
Trigger Event:
release
-
Statement type:
File details
Details for the file lavlab_shell-0.4.0-py3-none-any.whl.
File metadata
- Download URL: lavlab_shell-0.4.0-py3-none-any.whl
- Upload date:
- Size: 24.2 MB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
bea6e65da711aa85a41811f472cf4a439f97dca31e61416e427a7dde044f9650
|
|
| MD5 |
b162ae9b5d1d66c3fe763722c1d99e8c
|
|
| BLAKE2b-256 |
38ac438553043cbfc293b6070d47322462e63f7de68ae16e29ac315473202c33
|
Provenance
The following attestation bundles were made for lavlab_shell-0.4.0-py3-none-any.whl:
Publisher:
publish.yml on laviolette-lab/shell
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
lavlab_shell-0.4.0-py3-none-any.whl -
Subject digest:
bea6e65da711aa85a41811f472cf4a439f97dca31e61416e427a7dde044f9650 - Sigstore transparency entry: 1018255107
- Sigstore integration time:
-
Permalink:
laviolette-lab/shell@80f4b400fc5f0ef054431f3462925943f3ea40dc -
Branch / Tag:
refs/tags/v0.4.0 - Owner: https://github.com/laviolette-lab
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@80f4b400fc5f0ef054431f3462925943f3ea40dc -
Trigger Event:
release
-
Statement type: