Developer Guide
This guide is for developers who want to contribute to or extend CTHarvester.
Architecture Overview
Module Structure
CTHarvester follows a modular architecture:
CTHarvester/
├── core/ # Core business logic
│ ├── progress_tracker.py # Progress tracking
│ ├── progress_manager.py # Progress management
│ ├── thumbnail_manager.py # Thumbnail coordination
│ ├── thumbnail_generator.py # Thumbnail generation logic
│ ├── thumbnail_worker.py # Worker threads
│ ├── sequential_processor.py # Sequential processing (Phase 4.1)
│ ├── volume_processor.py # Volume processing
│ └── worker_manager.py # Worker management
├── ui/ # User interface
│ ├── main_window.py # Main application window (789 lines)
│ ├── ctharvester_app.py # Custom QApplication subclass
│ ├── handlers/ # UI handler modules (Phase 4)
│ │ ├── thumbnail_creation_handler.py # Thumbnail generation (Phase 4.2)
│ │ ├── directory_open_handler.py # Directory opening (Phase 4.3)
│ │ ├── view_manager.py # 3D view management (Phase 4.4)
│ │ ├── export_handler.py # Export operations
│ │ ├── file_handler.py # File operations
│ │ └── settings_handler.py # Settings management
│ ├── dialogs/ # Dialog windows
│ │ ├── progress_dialog.py # Progress display
│ │ ├── info_dialog.py # Information dialogs
│ │ └── shortcut_dialog.py # Keyboard shortcuts
│ ├── widgets/ # Custom widgets
│ │ ├── mcube_widget.py # 3D marching cubes viewer
│ │ ├── object_viewer_2d.py # 2D image viewer
│ │ └── vertical_stack_slider.py # Range slider
│ └── setup/ # UI setup modules
│ └── main_window_setup.py # Window initialization
├── utils/ # Utility functions
│ ├── settings_manager.py # User preferences (preferences.json)
│ ├── paths.py # User-data locations (single owner)
│ ├── common.py # Common utilities
│ ├── ui_utils.py # UI helper functions
│ ├── file_utils.py # File utilities
│ └── image_utils.py # Image processing utilities
├── config/ # Configuration
│ ├── constants.py # Application constants
│ ├── shortcuts.py # Keyboard shortcuts
│ └── tooltips.py # Tooltip definitions
├── security/ # Security modules
│ └── file_validator.py # File validation & path traversal prevention
└── tests/ # Test suite (1,295 tests)
├── integration/ # Integration tests
├── property/ # Property-based tests
└── test_*.py # Unit tests
Design Principles
Separation of Concerns: UI, business logic, and data handling are separate
Modularity: Each module has a single, well-defined responsibility
Testability: Core logic is independent of UI for easy testing
Thread Safety: Proper synchronization for multithreaded operations
Security First: Input validation and secure file operations
Key Components
Progress Tracking:
SimpleProgressTracker: Linear progress with ETAProgressManager: Weighted multi-level progressSignal/slot connections for UI updates
Thumbnail Generation:
ThumbnailCreationHandler: Orchestrates Rust/Python thumbnail generation (Phase 4.2)ThumbnailGenerator: Core thumbnail generation logicThumbnailManager: Coordinates worker threadsThumbnailWorker: Processes individual thumbnailsSequentialProcessor: Python fallback sequential processing (Phase 4.1)Support for both Rust (high-performance) and Python (fallback) implementations
UI Handlers (Phase 4 Refactoring):
ThumbnailCreationHandler: Manages thumbnail generation workflowsDirectoryOpenHandler: Handles directory selection and loadingViewManager: Manages 3D view updates and synchronizationExportHandler: Manages export operationsFileHandler: File operations and validationSettingsHandler: Window settings persistence
Settings Management:
JSON-based configuration
Platform-independent storage
Import/Export functionality
Dot notation access (
settings.get('app.language'))
Security:
SecureFileValidator: Path traversal preventionWhitelist-based file extension validation
Safe file operations
Development Setup
Prerequisites
Python 3.8+
Git
Virtual environment tool (venv or conda)
Optional: Rust toolchain for building native module
Setting Up Development Environment
Clone and setup:
git clone https://github.com/yourusername/CTHarvester.git cd CTHarvester # Create virtual environment python -m venv venv source venv/bin/activate # Linux/macOS # or venv\\Scripts\\activate # Windows # Install dependencies pip install -r requirements.txt pip install -r requirements-dev.txt # Development dependencies
Install pre-commit hooks:
pre-commit installRun tests:
pytest tests/
Code Style and Standards
Python Style Guide
We follow PEP 8 with some modifications:
Line length: 100 characters (not 79)
Use double quotes for strings
Use type hints for function signatures
Use Google-style docstrings
Example:
def process_image(
image_path: str,
threshold: int = 128,
invert: bool = False
) -> np.ndarray:
"""Process a single CT image.
Args:
image_path: Path to the image file.
threshold: Grayscale threshold value (0-255).
invert: Whether to invert grayscale values.
Returns:
Processed image as numpy array.
Raises:
FileNotFoundError: If image_path doesn't exist.
ValueError: If threshold is out of range.
"""
# Implementation
pass
Docstring Style
Use Google-style docstrings for all public APIs:
def function_name(param1: type1, param2: type2) -> return_type:
"""Short one-line summary.
Longer description if needed. Can span multiple paragraphs.
Args:
param1: Description of param1.
param2: Description of param2.
Returns:
Description of return value.
Raises:
ExceptionType: When this exception is raised.
Example:
>>> result = function_name("foo", 42)
>>> print(result)
'expected output'
"""
Type Hints
Use type hints for all function signatures:
from typing import Optional, List, Dict, Tuple
def process_files(
files: List[str],
options: Optional[Dict[str, Any]] = None
) -> Tuple[int, int]:
"""Process multiple files."""
pass
Testing
Test Organization
Tests are organized by module:
tests/
├── test_progress_tracker.py
├── test_thumbnail_manager.py
├── test_settings_manager.py
└── test_file_validator.py
Running Tests
Run all tests:
pytest
Run specific test file:
pytest tests/test_settings_manager.py
Run with coverage:
pytest --cov=. --cov-report=html
Run specific test:
pytest tests/test_settings_manager.py::test_get_nested_setting
Writing Tests
Example test structure:
import pytest
from core.progress_tracker import SimpleProgressTracker, ProgressInfo
class TestSimpleProgressTracker:
"""Tests for SimpleProgressTracker class."""
def test_initialization(self):
"""Test tracker initialization."""
tracker = SimpleProgressTracker(total_items=100)
assert tracker.completed_items == 0
assert tracker.total_items == 100
def test_update_progress(self):
"""Test progress update."""
tracker = SimpleProgressTracker(total_items=100)
tracker.update(increment=10)
assert tracker.completed_items == 10
def test_eta_calculation(self):
"""Test ETA calculation after sufficient samples."""
results = []
def callback(info: ProgressInfo):
results.append(info)
tracker = SimpleProgressTracker(
total_items=100,
callback=callback
)
for i in range(10):
time.sleep(0.1)
tracker.update()
# After min_samples_for_eta, should have ETA
assert results[-1].eta_seconds is not None
@pytest.mark.parametrize("total,increment", [
(100, 1),
(1000, 10),
(50, 5),
])
def test_various_increments(self, total, increment):
"""Test with various total/increment combinations."""
tracker = SimpleProgressTracker(total_items=total)
for i in range(0, total, increment):
tracker.update(increment=increment)
assert tracker.completed_items == total
Test Coverage Goals
Overall coverage: >70%
Core modules: >80%
Security modules: >90%
Contributing
Contribution Workflow
Fork and Clone:
Fork the repository on GitHub
Clone your fork locally
Add upstream remote:
git remote add upstream https://github.com/original/CTHarvester.git
Create Feature Branch:
git checkout -b feature/your-feature-name
Make Changes:
Write code
Add tests
Update documentation
Run tests:
pytestCheck style:
flake8orblack --check .
Commit:
git add . git commit -m "feat: Add your feature description"
Follow conventional commits format:
feat:: New featurefix:: Bug fixdocs:: Documentation changesrefactor:: Code refactoringtest:: Adding testschore:: Maintenance tasks
Push and Create PR:
git push origin feature/your-feature-name
Create pull request on GitHub
Fill out PR template
Link related issues
Wait for review
Code Review Process
All code changes go through review:
Automated Checks:
Tests must pass
Code coverage must not decrease
Style checks must pass
Manual Review:
At least one approving review required
Address review comments
Update as needed
Merge:
Squash and merge preferred
Delete branch after merge
Pull Request Guidelines
Good PR:
Focused on single feature/fix
Includes tests
Updates documentation
Clear description
Links to related issues
PR Template:
## Description
Brief description of changes
## Type of Change
- [ ] Bug fix
- [ ] New feature
- [ ] Documentation update
- [ ] Refactoring
## Testing
- [ ] Tests added/updated
- [ ] All tests passing
- [ ] Manual testing performed
## Checklist
- [ ] Code follows style guidelines
- [ ] Self-review performed
- [ ] Documentation updated
- [ ] No new warnings
## Related Issues
Closes #123
Building and Packaging
Building Rust Module
cd rust_thumbnail
cargo build --release
cd ..
The compiled library will be placed in target/release/.
Creating Executable
Using PyInstaller:
# Windows
pyinstaller --onefile --noconsole --icon=CTHarvester_64.png CTHarvester.py
# Linux/macOS
pyinstaller --onefile --icon=CTHarvester_64.png CTHarvester.py
Output:
Executable in
dist/directoryStandalone, no Python required
Building Documentation
cd docs
make html
Output in docs/_build/html/.
Release Process
Update Version:
Update
config/constants.pyUpdate
docs/conf.pyUpdate
setup.py(if using)
Update Changelog:
Add release notes
List all changes since last release
Create Release:
git tag -a v0.3.0 -m "Release v0.3.0" git push origin v0.3.0
Build Artifacts:
Build executables for all platforms
Build documentation
Create source distribution
Publish Release:
Create GitHub release
Attach built artifacts
Copy changelog to release notes
Mark as latest release
Debugging Tips
Logging
CTHarvester uses Python’s logging module:
import logging
logger = logging.getLogger(__name__)
logger.debug("Detailed information")
logger.info("General information")
logger.warning("Warning message")
logger.error("Error occurred")
Set log level in settings or via command line.
Common Debugging Scenarios
Threading Issues:
Use
QMutexLockerfor thread-safe operationsCheck for race conditions with
threading.current_thread()Use
logginginstead ofprint()in threads
Memory Leaks:
Use
memory_profilerto track memory usageCheck for circular references
Use weak references where appropriate
Performance Issues:
Profile with
cProfileUse
line_profilerfor line-by-line profilingCheck I/O operations (often the bottleneck)
Qt/GUI Issues:
Only update UI from main thread
Use signals/slots for cross-thread communication
Check event loop is running
Resources
Documentation
Tools
pytest: Testing framework
ruff: Linter and formatter (replaced black, isort, flake8, pyupgrade and pylint)
mypy: Type checker
bandit: Security linter
coverage.py: Coverage reporting
PyInstaller: Executable builder
In-repo notes
Longer-form developer references live as Markdown in the repository rather than
in this manual, because they are for people working on CTHarvester rather than
using it. They are not part of this site – see docs/README.md for the
convention.
ARCHITECTURE.md – module layout and data flow
CODE_QUALITY.md – ruff, mypy, bandit, pre-commit
developer_guide/error_recovery.md – error handling patterns
developer_guide/performance.md – profiling and optimisation
RELEASE_PROCESS.md – cutting a release
Community
GitHub Issues: Bug reports and feature requests
Discussions: Questions and general discussion
Pull Requests: Code contributions
Wiki: Additional documentation
Getting Help
Check this documentation
Search existing issues
Ask in GitHub Discussions
Create new issue if needed
When asking for help, include:
Python version
Operating system
CTHarvester version
Error message (full traceback)
Minimal reproduction steps
What you’ve tried