Contributing to Structum¶
Thank you for considering contributing to Structum! 🎉
We want to make contributing as easy and transparent as possible. This document outlines the process and guidelines.
🎯 Code of Conduct¶
This project adheres to the Contributor Covenant Code of Conduct. By participating, you are expected to uphold this code.
🚀 Getting Started¶
Prerequisites¶
Python 3.11+
Git
uv (recommended) or pip
Development Setup¶
# 1. Clone repository
git clone https://github.com/PythonWoods/structum.git
cd structum
# 2. Install all packages + dev dependencies with uv (recommended)
uv sync --extra dev
# 3. Setup pre-commit hooks
pre-commit install
Note:
uv sync --extra devinstalls all workspace packages (packages/*) in editable mode plus development tools (mypy, ruff, black, pytest, etc.).
Alternative: Manual pip install¶
# If not using uv, you can install packages individually
pip install -e "packages/core[dev]"
pip install -e "packages/dynaconf"
pip install -e "packages/bootstrap"
# ... other packages as needed
🏷️ SPDX Headers & License Policy¶
Standard Header for New Files¶
All source files (.py, .toml, .yaml) MUST include SPDX headers:
# SPDX-FileCopyrightText: 2026 Your Name <your.email@example.com>
# SPDX-License-Identifier: Apache-2.0
Adding Your Copyright to New Files¶
Recommended: Use --auto to automatically detect your git config:
# Auto-detect from git config (user.name and user.email)
structum license add-header --auto path/to/newfile.py
# Automatically generates:
# SPDX-FileCopyrightText: 2026 Your Name <your@email.com>
# SPDX-License-Identifier: Apache-2.0
Alternative: Manual specification:
# Specify author explicitly
structum license add-header path/to/newfile.py \
--author "Your Name" --email "your@email.com"
Default (core team only):
# Uses PythonWoods Team as copyright holder
structum license add-header path/to/newfile.py
Modifying Existing Files¶
When editing files created by others:
Small changes (< 10 lines): Keep existing headers unchanged
Substantial contributions (refactors, new features): Add your copyright line
# SPDX-FileCopyrightText: 2026 PythonWoods Team
# SPDX-FileCopyrightText: 2026 Your Name <your.email@example.com>
# SPDX-License-Identifier: Apache-2.0
Verify Compliance¶
Before submitting a PR:
# Check all files have proper SPDX headers
structum license check
# Expected: ✅ All files are properly licensed!
See: License Management Guide for complete policy.
📋 How to Contribute¶
Reporting Bugs¶
Use the Bug Report template:
Search existing issues first
Use the bug report template
Include minimal reproduction
Specify environment details
Suggesting Features¶
Use the Feature Request template:
Check the Roadmap first
Describe the problem clearly
Propose your solution
Consider alternatives
Proposing Plugins¶
Use the Plugin Proposal template:
Review existing plugins
Check ROADMAP for planned plugins
Describe plugin purpose and interface
Provide implementation outline
🔧 Development Workflow¶
1. Branch Strategy¶
# Create feature branch
git checkout -b feat/plugin-name
# Create fix branch
git checkout -b fix/issue-description
2. Code Standards¶
Type Hints: 100% coverage, mypy strict mode
mypy packages/*/src/ --strict
Formatting: Black with default settings
black packages/*/src/
Linting: Ruff with project config
ruff check packages/*/src/
Tests: >90% coverage required
pytest tests/ -v --cov --cov-report=term-missing
3. Plugin Development¶
Follow the AI Development Guide in docs/ai/:
Read ROADMAP for plugin spec
Create Protocol in
packages/core/src/structum/[name]/Implement in
packages/[name]/src/structum/plugins/[name]/Add tests with >90% coverage
Update documentation
Add usage example in
demo/
Mandatory Checklist:
✅ Protocol interface in core
✅ Configuration-driven (no hardcoded values)
✅ Metrics emission via
get_metrics()✅ Structured logging via
get_logger()✅ Health checks implemented
✅ Graceful shutdown handling
✅ Complete documentation
✅ Tests >90% coverage
4. Commit Messages¶
We follow Conventional Commits:
<type>(<scope>): <description>
[optional body]
[optional footer]
Types:
feat: New featurefix: Bug fixdocs: Documentation changesrefactor: Code refactoringtest: Test changeschore: Maintenance tasksci: CI/CD changes
Examples:
feat(database): add SQLAlchemy provider
fix(auth): handle expired JWT tokens
docs(roadmap): update plugin priorities
refactor(cache): extract Redis client
test(messaging): add pub/sub integration tests
chore(deps): update dependencies
ci(workflow): add coverage reporting
5. Pull Request Process¶
Update Documentation: README, docs/, CHANGELOG
Run Quality Gates:
# All must pass mypy packages/*/src/ --strict black --check packages/*/src/ ruff check packages/*/src/ pytest --covUpdate CHANGELOG.md: Add entry under “Unreleased”
Create PR: Use the PR template
Request Review: Assign reviewers
Address Feedback: Respond to all comments
Squash Commits: Before merge (if requested)
📚 Documentation Guidelines¶
Code Documentation¶
Docstrings: Google style
def get_connection(self, timeout: int = 30) -> Connection:
"""Get database connection with timeout.
Args:
timeout: Connection timeout in seconds
Returns:
Active database connection
Raises:
ConnectionError: If connection fails
Example:
>>> db = get_database()
>>> conn = db.get_connection(timeout=10)
"""
Markdown Documentation¶
Use headers properly (H1 = title, H2 = sections)
Include code examples
Add links to related docs
Keep it concise but complete
🧪 Testing Guidelines¶
Test Structure¶
# tests/test_plugin_name.py
import pytest
from structum.plugin import PluginInterface
def test_basic_functionality():
"""Test core functionality."""
plugin = ConcretePlugin()
result = plugin.operation()
assert result is not None
def test_health_check():
"""Test health check implementation."""
plugin = ConcretePlugin()
health = plugin.health_check()
assert health["status"] == "healthy"
def test_graceful_shutdown():
"""Test shutdown doesn't raise."""
plugin = ConcretePlugin()
plugin.shutdown() # Should not raise
@pytest.fixture
def plugin_instance():
"""Fixture for plugin instance."""
return ConcretePlugin()
Coverage Requirements¶
Overall: >90%
New code: 100%
Core modules: 95%+
🏗️ Architecture Principles¶
Core Principles:
Protocol-First: Core has ONLY interfaces
Configuration-Driven: No hardcoded values
Observable: Metrics + logging everywhere
Testable: Easy to mock and test
Documented: Self-explanatory code + docs
Anti-Patterns to Avoid:
❌ Core depending on plugins
❌ Hardcoded configuration
❌ Missing type hints
❌ No metrics/logging
❌ Untested code
📦 Release Process¶
For Maintainers:
Update CHANGELOG.md
Bump version (setuptools-scm handles this via tags)
Create release PR
Merge to main
Create GitHub release with tag
vX.Y.ZCI automatically publishes to PyPI
💬 Communication¶
GitHub Issues: Bug reports, feature requests
Pull Requests: Code contributions
Discussions: General questions, ideas
Discord (if available): Real-time chat
📄 License¶
By contributing, you agree that your contributions will be licensed under the Apache License 2.0.
🎓 Resources for Contributors¶
ROADMAP - Plugin development guide
AI Guide - AI-assisted development guides
Architecture Concepts - Deep dives
Existing Plugins - Reference implementations
Questions? Open an issue or start a discussion!
Thank you for contributing to Structum! 🚀✨