paper-trail-api / CONTRIBUTING.md
Hoe
Deploying Backend API
b339b93

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

  1. Clone the repository

    git clone https://github.com/Operation-Hope/paper-trail-api.git
    cd paper-trail-api
    
  2. Create a virtual environment and install dependencies

    uv venv
    source .venv/bin/activate  # On Windows: .venv\Scripts\activate
    uv sync --all-extras
    
  3. Install the duckdb-loader package in development mode

    uv pip install -e duckdb_loader/
    
  4. Set up pre-commit hooks

    uv run pre-commit install
    
  5. Copy environment template

    cp .env.example .env
    # Edit .env with your configuration
    

Development Workflow

Code Quality

We use the following tools to maintain code quality:

  • Ruff - Linting and formatting
  • ty - Type checking
  • pytest - Testing

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 features
  • fix/description - Bug fixes
  • docs/description - Documentation updates
  • refactor/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

  1. Create a feature branch from main
  2. Make your changes
  3. Ensure all checks pass locally
  4. Push your branch and create a PR
  5. Fill out the PR template
  6. 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.py for 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.