Skip to main content

SHELL Highlights Epithelium and Lumen Locations — whole-slide H&E segmentation

Project description

SHELL — SHELL Highlights Epithelium and Lumen Locations

Build Tests Lint PyPI - Version PyPI - Python Version


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

  1. Place the new .pth file in src/shell/weights/.
  2. Add an entry to MODEL_REGISTRY in src/shell/model.py:
    MODEL_REGISTRY: dict[str, str] = {
        "v1": "model_v1.pth",
        "v2": "model_v2.pth",  # new
    }
    
  3. Update LATEST_MODEL:
    LATEST_MODEL: str = "v2"
    
  4. 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:

  1. Builds a wheel and sdist and publishes them to PyPI via trusted publishing (OIDC — no API tokens needed).
  2. Builds standalone binaries for Linux (x86_64) and macOS (x86_64 + arm64) using Nuitka with Python 3.12.
  3. 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)

  1. Go to https://pypi.org/manage/account/publishing/.
  2. Add a pending publisher:
    • PyPI project name: shell
    • Owner: laviolette-lab
    • Repository: shell
    • Workflow name: publish.yml
    • Environment name: pypi

One-Time Setup (GitHub)

  1. 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

lavlab_shell-0.3.0.tar.gz (24.2 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

lavlab_shell-0.3.0-py3-none-any.whl (24.2 MB view details)

Uploaded Python 3

File details

Details for the file lavlab_shell-0.3.0.tar.gz.

File metadata

  • Download URL: lavlab_shell-0.3.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

Hashes for lavlab_shell-0.3.0.tar.gz
Algorithm Hash digest
SHA256 60e73c9b48854ce3d52b932c272dd8bc52c8a0adc4d17ada23f82e7648eafed9
MD5 06b12503ddf2d8372a497dda87263f1a
BLAKE2b-256 92159b9820d72e025ae6fece5c06d6d294739f0642eeee125bdb8ba85b2481cb

See more details on using hashes here.

Provenance

The following attestation bundles were made for lavlab_shell-0.3.0.tar.gz:

Publisher: publish.yml on laviolette-lab/shell

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file lavlab_shell-0.3.0-py3-none-any.whl.

File metadata

  • Download URL: lavlab_shell-0.3.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

Hashes for lavlab_shell-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 7a6354636ee0c6bc79b7b2f523628dfc9105de60b3b7b111001e70e8b0f3905a
MD5 e1296c805f485aebf3e3c4b158d70878
BLAKE2b-256 d70daf99d936207411c8d09cfddefcd2c6e6bd07b03dd95d2b6568cfa705aa45

See more details on using hashes here.

Provenance

The following attestation bundles were made for lavlab_shell-0.3.0-py3-none-any.whl:

Publisher: publish.yml on laviolette-lab/shell

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page