Thank you for your interest in contributing to ndevio! This document provides guidelines for development and contributions.
For development, clone the repository and install with the dev dependency group:
git clone https://github.com/ndev-kit/ndevio.git
cd ndevio
pip install -e . --group devThis includes pytest, pytest-cov, pytest-qt, tox-uv, napari, and pyqt6.
Run tests with:
pytest -v --cov=ndevio --cov-report=htmlYou can use Pixi for reproducible development environments:
git clone https://github.com/ndev-kit/ndevio.git
cd ndevio
pixi install -e dev
pixi run -e dev testOr activate the environment and run commands directly:
pixi shell -e dev
pytest -vThe following components represent stable, mature patterns that reflect the goals of the ndevio API:
The nImage class (nimage.py) extends bioio's BioImage with napari-specific functionality. This is the core programmatic API for ndevio and follows these principles:
- Metadata translation: Converts bioio metadata (physical pixel sizes, dimension properties, OME metadata) to napari layer metadata (scale, axis_labels, units)
- Lazy loading support: Automatically determines whether to load data in-memory or use dask based on file size and available RAM
- Layer data tuples: Provides
get_layer_data_tuples()method that returns napari-readyLayerDataTupleobjects - Channel splitting: Handles multi-channel images by creating separate layer data tuples per channel
- Separation of concerns: No Qt or napari widget dependencies in core functionality
The napari reader plugin (_napari_reader.py) implements the npe2 reader specification:
- Plugin discovery: Registers file extensions and provides reader selection
- Scene handling: Integrates with the Scene Widget for multi-scene files
- Settings integration: Respects user preferences from ndev-settings
- Error handling: Provides helpful suggestions for missing bioio plugins
This module is the bridge between napari and nImage, translating drag-and-drop file operations into proper layer creation.
- Core logic separate from UI: Business logic in
nimage.py,_layer_utils.py, etc. should have no Qt or napari imports (except type hints) - Lazy imports: Expensive imports (Qt, napari widgets) should be lazy-loaded to keep startup fast
- Settings-driven behavior: Use [ndev-settings] for user-configurable behavior rather than hardcoding choices
- bioio compatibility: Stay aligned with bioio's data model and avoid reinventing functionality