Releases: sebi06/czitools
v0.13.2 - Fix Threading Issues with aicspylibczi on Linux + Napari
Release Notes - v0.13.2
Release Date: January 26, 2026
🔴 Critical Fix: Linux + Napari Threading Issues
This release addresses critical threading crashes when using czitools with Napari on Linux systems.
Problem Resolved
aicspylibczi library caused crashes when used concurrently with Napari (PyQt) on Linux, affecting:
- CZI file loading in Napari plugins
- Planetable extraction in GUI applications
- Mosaic tile reading with concurrent operations
Root Cause
- aicspylibczi is NOT thread-safe and conflicts with PyQt event loop on Linux
- pylibCZIrw is thread-safe but cannot read individual subblocks/tiles
✅ New Features
1. Safe Mode (Primary Solution) ⭐
Environment variable control to disable problematic library:
import os
os.environ["CZITOOLS_DISABLE_AICSPYLIBCZI"] = "1"
from czitools.read_tools import read_tools
array, metadata = read_tools.read_6darray("file.czi", use_dask=True)Benefits:
- 100% stable with Napari on Linux
- No threading conflicts
- No performance loss (dask lazy loading)
- Recommended for all Napari users on Linux
2. Thread Locks (Backward Compatibility)
Global RLock protection added to:
read_tiles()functionget_planetable()function
Note: May still experience issues with Napari on Linux. Safe mode is recommended.
3. Platform Detection & Warnings
Automatic Linux detection with user warnings:
from czitools.utils.napari_helpers import warn_if_unsafe_for_napari
warn_if_unsafe_for_napari()4. New Helper Utilities
src/czitools/utils/napari_helpers.py (NEW):
enable_napari_safe_mode()- Enable safe mode programmaticallyis_napari_safe_mode()- Check safe mode statuscheck_napari_compatibility()- Verify environment safetyget_recommended_read_params()- Get optimal parameterswarn_if_unsafe_for_napari()- Warning for unsafe conditions
src/czitools/utils/threading_helpers.py (NEW):
with_aics_lock(func)- Decorator for thread-safe operationsis_napari_safe()- Check safe mode statuswarn_if_unsafe_for_napari()- Linux platform warnings
📝 Changes
Modified Files
- src/czitools/read_tools/read_tools.py - Added safe mode + thread locks
- src/czitools/utils/planetable.py - Added safe mode + thread locks
- src/czitools/metadata_tools/czi_metadata.py - Safe mode support
- README.md - Added prominent warning section
- setup.cfg - Updated version to 0.13.2
- tox.ini - Updated test configuration
New Files
- src/czitools/utils/threading_helpers.py - Thread-safety utilities
- src/czitools/utils/napari_helpers.py - Napari integration helpers
- src/czitools/_tests/test_napari_safe_mode.py - Test suite (7 tests)
Documentation
- docs/threading_considerations.md - Comprehensive threading guide
- docs/NAPARI_FIX.md - Quick-fix guide
- docs/FINAL_SOLUTION.md - Complete solution documentation
- docs/IMPLEMENTATION_SUMMARY.md - Technical details
- docs/LINUX_NAPARI_PLANETABLE.md - Linux-specific guide
Examples
- demo/scripts/napari_safe_loading.py - Working example
- demo/scripts/napari_with_planetable_linux.py - Linux planetable example
- demo/scripts/napari_plugin_example.py - Plugin integration
- demo/scripts/napari_with_process_isolation.py - Process isolation pattern
🚀 Recommended Usage
For Linux + Napari Users:
import os
os.environ["CZITOOLS_DISABLE_AICSPYLIBCZI"] = "1"
from czitools.read_tools import read_tools
import napari
array, metadata = read_tools.read_6darray("file.czi", use_dask=True)
viewer = napari.Viewer()
viewer.add_image(array)For Windows/macOS:
No changes needed - works as before.
For Planetable Extraction:
Use sequential pattern (extract before Napari):
from czitools.utils.planetable import get_planetable
# Extract planetable BEFORE starting Napari
df, _ = get_planetable("file.czi")
# THEN start Napari
import napari
viewer = napari.Viewer()🔄 Backward Compatibility
- ✅ No breaking changes for Windows/macOS users
- ✅ Existing code works without modifications
- ✅ Safe mode is opt-in via environment variable
- ✅ Thread locks provide basic protection by default
⚠️ Behavioral Changes
When CZITOOLS_DISABLE_AICSPYLIBCZI=1 is set:
read_tiles()raisesRuntimeError(useread_6darray()instead)get_planetable()returns empty DataFrame (extract before Napari)CziMetadata.attachment_inforeturnsNone- All other functionality remains unchanged
📊 Statistics
- Total Changes: 19 files
- Insertions: +2,542 lines
- Deletions: -396 lines
- New Tests: 7 (all passing)
- New Documentation: 5 files
- New Examples: 4 scripts
🧪 Testing
All tests passing:
pytest src/czitools/_tests/test_napari_safe_mode.py -vTest Coverage:
- Safe mode enable/disable
- Environment variable detection
- Thread lock functionality
- read_tiles behavior in safe mode
- get_planetable behavior in safe mode
- read_6darray compatibility
- Platform detection
📚 Documentation
Comprehensive documentation available:
🎯 Migration Guide
If you use read_6darray():
✅ No changes needed! Works perfectly in all modes.
If you use read_tiles() or get_planetable() with Napari on Linux:
Enable safe mode and switch to read_6darray():
os.environ["CZITOOLS_DISABLE_AICSPYLIBCZI"] = "1"
array, metadata = read_tools.read_6darray("file.czi") # Use this insteadIf you need planetables with Napari:
Use sequential pattern:
# 1. Extract planetable BEFORE Napari
df, _ = get_planetable("file.czi")
# 2. THEN start Napari
import napari
viewer = napari.Viewer()🙏 Acknowledgments
Thanks to all users who reported threading issues on Linux systems and helped identify the root cause.
🔗 Related
- Pull Request: #111 - Fix threading issues with aicspylibczi on Linux + Napari
- Branch: improve_stability
For detailed technical information, see the Implementation Summary.
Release 0.13.1
- remove tqdm
Release v0.12.0
This release introduces significant improvements to the CZI reading capabilities, including a new read_scenes() function, URL support for lazy loading, and comprehensive test coverage.
New Features
read_scenes() Function
- Read all 2D planes from CZI files grouped by scene
- Lazy loading with use_dask=True
- xarray support with labeled dimensions
- Scene stacking for consistent shapes
URL Support for Lazy Loading
- get_pyczi_readertype() utility function
- Direct URL reading without full metadata load
Improved read_6darray_lazy()
- Added use_xarray parameter
- Fixed attribute errors
- URL-based reading support
read_6darray() Improvements
- Fixed type hints
- Simplified logic
- Better logging
Test Coverage
- 33 new tests for read_scenes() and read_6darray_lazy()
- Tests for get_pyczi_readertype()
Breaking Changes
None - backwards compatible"
Release v0.11.2
- minor bugfixes
- more OME-ZARR examples
Release v0.11.1
Release v0.11.0
Release 0.10.3
- minor bugfixes
Release v0.10.2
- correct README.md
- make additional test work for python 3.9
- move some dependencies to czitools[all]
Release 0.10.0
Release 0.10.0
- refactoring of reading planetable
- reading the planetable now allows filtering during reading
- improves tests
- add new dependencies to prepare for using bioio & bioio-czi soon
Remove napari_tools and add xarray option
- remove napari_tools to reduce dependencies and simplify package
- add option to read 6d array from CZI image file as xarry