Contributing to SoS Notebook
November 5, 2025 · View on GitHub
Thank you for your interest in contributing to SoS Notebook! This document provides comprehensive guidelines for setting up your development environment, making changes, and submitting contributions.
Table of Contents
- Prerequisites
- Development Setup
- Development Workflow
- Code Quality
- Testing
- Building and Releasing
- Submitting Changes
- Project Structure
- Troubleshooting
Prerequisites
Required Software
- Python 3.8+ - SoS Notebook requires Python 3.8 or later
- uv - Fast Python package installer and resolver
# Install uv (recommended method) curl -LsSf https://astral.sh/uv/install.sh | sh # Or via pip pip install uv # Or via homebrew (macOS) brew install uv - Git - For version control
- Docker (optional) - For running the full test suite
Verify Installation
python --version # Should be 3.8+
uv --version # Should be 0.4.0+
git --version
Development Setup
1. Clone the Repository
git clone https://github.com/vatlab/sos-notebook.git
cd sos-notebook
2. Set Up Development Environment
We use invoke for task automation. The dev-setup command will:
- Create a virtual environment with uv
- Install the package in development mode
- Install all development dependencies
- Set up pre-commit hooks
# One-command setup
invoke dev-setup
# Activate the virtual environment
source .venv/bin/activate
3. Manual Setup (Alternative)
If you prefer manual setup:
# Create virtual environment
uv venv
# Activate virtual environment
source .venv/bin/activate # Linux/macOS
# or
.venv\Scripts\activate # Windows
# Install package in development mode with dependencies
uv pip install -e .
uv sync --dev
# Install pre-commit hooks
pre-commit install
4. Verify Setup
# List available development tasks
invoke --list
# Run a quick check
invoke format --check
invoke lint
Development Workflow
Daily Development Commands
# Activate virtual environment (if not already active)
source .venv/bin/activate
# Make your changes...
# Format code
invoke format
# Check and fix linting issues
invoke lint --fix
# Run tests
invoke test
# Run all quality checks
invoke check
Task Automation with Invoke
We use invoke for development task automation. All tasks are defined in tasks.py.
Core Tasks
# Environment management
invoke dev-setup # Complete development setup
invoke venv-create # Create virtual environment
invoke uv-sync # Sync dependencies
invoke uv-lock # Update lock file
# Code quality
invoke format # Format code with ruff
invoke format --check # Check formatting without changes
invoke lint # Run linting
invoke lint --fix # Run linting with auto-fix
invoke check # Run all quality checks (format, lint, test)
# Testing
invoke test # Run tests (skips Docker/selenium tests)
invoke test --verbose # Verbose test output
invoke test --coverage # Run tests with coverage report
invoke test-docker # Full test suite in Docker (CI environment)
# Building
invoke build # Build source and wheel distributions
invoke build --clean # Clean and rebuild
invoke clean # Clean build artifacts
invoke install # Install package in development mode
# Release
invoke release-check # Comprehensive pre-release checks
Advanced Tasks
# Run specific test paths
invoke test --path="test/test_magics.py"
# Generate coverage report
invoke test --coverage
# Clean everything
invoke clean --all
Code Quality
Code Formatting and Linting
We use ruff for both code formatting and linting. Ruff is extremely fast and replaces multiple tools (yapf, flake8, isort, etc.).
Configuration
Ruff is configured in pyproject.toml:
[tool.ruff]
target-version = "py38"
line-length = 88
[tool.ruff.lint]
select = ["E", "W", "F", "I", "B", "C4", "UP"]
ignore = ["E501"] # line too long (handled by formatter)
[tool.ruff.format]
quote-style = "double"
indent-style = "space"
Running Code Quality Checks
# Format code
invoke format
# Check formatting without making changes
invoke format --check
# Run linting
invoke lint
# Auto-fix linting issues
invoke lint --fix
# Run all quality checks
invoke check
Pre-commit Hooks
Pre-commit hooks are automatically installed during invoke dev-setup. They run on every commit to ensure code quality:
- Code formatting with ruff
- Linting with ruff
- Basic file checks (trailing whitespace, file size, etc.)
To run pre-commit manually:
pre-commit run --all-files
Testing
Test Structure
test/- Main test directorytest/test_*.py- Unit and integration tests- Docker-based integration tests simulate real Jupyter environments
Running Tests
# Quick tests (skip Docker/selenium dependencies)
invoke test
# Verbose output
invoke test --verbose
# Run with coverage
invoke test --coverage
# Run specific test file
invoke test --path="test/test_magics.py"
# Full test suite in Docker (as run in CI)
invoke test-docker
Test Dependencies
Some tests require additional dependencies:
- Selenium - For frontend integration tests
- Docker - For containerized testing environment
- ImageMagick - For image processing tests
These are automatically skipped if not available, with appropriate skip messages.
Writing Tests
- Follow pytest conventions
- Use the
NotebookTestbase class for kernel tests - Mock external dependencies when possible
- Add integration tests for new features
Building and Releasing
Modern Build System
SoS Notebook uses a modern Python build system based on:
pyproject.tomlfor project configuration (PEP 517/518)uvfor dependency managementbuildmodule for creating distributions
Building Distributions
# Build both source and wheel distributions
invoke build
# Clean build artifacts first
invoke build --clean
# Manual build (alternative)
uv run python -m build
Release Preparation
Before releasing:
# Run comprehensive pre-release checks
invoke release-check
# This runs:
# 1. All quality checks (format, lint, test)
# 2. Clean build
# 3. Distribution verification
Version Management
- Update version in
pyproject.toml - Update version in
src/sos_notebook/_version.py - Update
CHANGELOG.md(if exists) - Run
invoke release-check - Create git tag and push
Submitting Changes
Pull Request Process
- Fork the repository on GitHub
- Create a feature branch from
master:git checkout -b feature/your-feature-name - Make your changes following the development workflow
- Run quality checks:
invoke check - Commit your changes with descriptive messages:
git add . git commit -m "Add feature: description of changes" - Push to your fork:
git push origin feature/your-feature-name - Create a Pull Request on GitHub
Commit Message Guidelines
- Use clear, descriptive commit messages
- Start with a verb in present tense ("Add", "Fix", "Update", "Remove")
- Limit first line to 72 characters
- Reference issues when applicable: "Fix #123: description"
Pull Request Guidelines
- Title: Clear, descriptive title
- Description: Explain what changes were made and why
- Testing: Describe how the changes were tested
- Documentation: Update documentation if needed
- Breaking Changes: Clearly mark any breaking changes
Project Structure
sos-notebook/
├── src/sos_notebook/ # Main package source
│ ├── __init__.py
│ ├── kernel.py # Main SoS kernel
│ ├── subkernel.py # Multi-language kernel management
│ ├── magics.py # Jupyter magic commands
│ ├── converter.py # Notebook conversion utilities
│ └── ...
├── test/ # Test suite
│ ├── test_kernel.py
│ ├── test_magics.py
│ └── ...
├── development/ # Docker development environment
├── tasks.py # Invoke task definitions
├── pyproject.toml # Project configuration
├── uv.lock # Dependency lock file
├── README.md # Project overview
├── CONTRIBUTING.md # This file
└── CLAUDE.md # Claude Code development guide
Key Files
pyproject.toml- Modern Python project configurationtasks.py- Development task automation with invokeuv.lock- Locked dependency versions for reproducible buildsCLAUDE.md- Development guidance for Claude Code AI assistant
Troubleshooting
Common Issues
Virtual Environment Issues
# Remove and recreate virtual environment
rm -rf .venv
invoke venv-create
source .venv/bin/activate
invoke uv-sync
Dependency Issues
# Update dependencies
invoke uv-sync
# Regenerate lock file
invoke uv-lock
Import Errors
# Reinstall package in development mode
uv pip install -e .
Test Failures
# Run tests with verbose output
invoke test --verbose
# Run specific test file
invoke test --path="test/test_specific.py"
# Skip Docker tests if Docker isn't available
invoke test # Docker tests are skipped automatically
Performance Issues
- Slow dependency resolution: uv is much faster than pip, but if you experience issues, try clearing cache:
uv cache clean - Slow tests: Use
invoke testinstead ofinvoke test-dockerfor faster iteration
Getting Help
- Check existing issues: GitHub Issues
- Search documentation: SoS Documentation
- Create a new issue: Include:
- Python version (
python --version) - uv version (
uv --version) - Operating system
- Full error message
- Steps to reproduce
- Python version (
Development Philosophy
- Modern tooling: We use the latest and fastest Python development tools
- Developer experience: Commands should be simple and fast
- Code quality: Automated formatting and linting
- Testing: Comprehensive tests including Docker-based integration tests
- Documentation: Clear documentation for users and developers
Thank you for contributing to SoS Notebook! 🎉