Spaces:
Runtime error
Runtime error
Contributing to Paper Trail API
Thank you for your interest in contributing to Paper Trail API! This document provides guidelines and instructions for contributing.
Development Setup
Prerequisites
- Python 3.13+
- uv (recommended package manager)
- Git
Getting Started
Clone the repository
git clone https://github.com/Operation-Hope/paper-trail-api.git cd paper-trail-apiCreate a virtual environment and install dependencies
uv venv source .venv/bin/activate # On Windows: .venv\Scripts\activate uv sync --all-extrasInstall the duckdb-loader package in development mode
uv pip install -e duckdb_loader/Set up pre-commit hooks
uv run pre-commit installCopy environment template
cp .env.example .env # Edit .env with your configuration
Development Workflow
Code Quality
We use the following tools to maintain code quality:
Running Checks Locally
# Linting
uv run ruff check .
# Auto-fix linting issues
uv run ruff check --fix .
# Formatting
uv run ruff format .
# Type checking
uv run ty check duckdb_loader/
# Run tests
uv run pytest tests/ -v
# Run tests with coverage
uv run pytest tests/ --cov=duckdb_loader --cov-report=term-missing
Pre-commit Hooks
Pre-commit hooks run automatically on git commit. They check:
- Ruff linting and formatting
- Trailing whitespace
- YAML validity
- Large files
- Merge conflicts
- Private keys
To run hooks manually:
uv run pre-commit run --all-files
Making Changes
Branch Naming
Use descriptive branch names:
feature/description- New featuresfix/description- Bug fixesdocs/description- Documentation updatesrefactor/description- Code refactoring
Commit Messages
Write clear, concise commit messages:
- Use present tense ("Add feature" not "Added feature")
- First line should be 50 characters or less
- Include context in the body if needed
Example:
Add cycle filter preset for recent elections
Adds `recent_cycles(n)` function that returns a CycleFilter
for the last N election cycles, defaulting to 4 (2018-2024).
Pull Requests
- Create a feature branch from
main - Make your changes
- Ensure all checks pass locally
- Push your branch and create a PR
- Fill out the PR template
- Request review
PR titles should be descriptive and follow the same guidelines as commit messages.
Testing
Running Tests
# Run all tests
uv run pytest tests/ -v
# Run specific test file
uv run pytest tests/test_filters.py -v
# Run specific test class or function
uv run pytest tests/test_filters.py::TestCycleFilter -v
uv run pytest tests/test_filters.py::TestCycleFilter::test_single_cycle_match -v
# Run with coverage
uv run pytest tests/ --cov=duckdb_loader --cov-report=html
Writing Tests
- Place tests in the
tests/directory - Name test files
test_*.py - Name test functions
test_* - Use fixtures from
conftest.pyfor shared data - Add markers for slow or integration tests:
@pytest.mark.slow def test_large_dataset(): ... @pytest.mark.integration def test_postgres_connection(): ...
Test Coverage
We aim for high test coverage on core functionality:
- Filters and filter presets
- Schema creation and validation
- Data loading logic (unit tests with mocks)
Project Structure
paper-trail-api/
βββ duckdb_loader/ # Main Python package
β βββ duckdb_loader/ # Package source
β βββ cli.py # CLI commands
β βββ filters.py # Data filters
β βββ loader.py # DuckDB loading
β βββ postgres_loader.py # PostgreSQL loading
β βββ schema.py # Schema definitions
βββ scripts/ # Utility scripts
βββ tests/ # Test suite
βββ docs/ # Documentation
βββ database/ # SQL schemas
βββ examples/ # Usage examples
βββ data/ # Data storage (gitignored)
Code Style
Python
- Follow PEP 8 (enforced by Ruff)
- Use type hints for function signatures
- Write docstrings for public functions and classes
- Keep functions focused and small
- Prefer composition over inheritance
Documentation
- Update README.md for user-facing changes
- Add docstrings for new public APIs
- Update examples if behavior changes
Getting Help
- Open an issue for bugs or feature requests
- Check existing issues before creating new ones
- Join discussions in pull requests
License
By contributing, you agree that your contributions will be licensed under the MIT License.