Thanks for your interest in contributing! This guide covers how to set up the project and submit changes.
# Clone and install
git clone https://github.com/nicweber/campLinks.git
cd campLinks
uv syncThis installs all runtime and dev dependencies into a .venv.
- Create a branch for your change.
- Make your edits.
- Run the checks below before opening a PR.
# Tests
uv run pytest tests/
# Type checking
uv run mypy camplinks/
# Linting and formatting
uv run ruff check .
uv run ruff format .All four must pass cleanly.
uv run pytest tests/test_db.py::TestUpsertElection::test_insert_returns_id- Polars only (never pandas), orjson for JSON.
- All functions need type hints and docstrings (Args / Returns / Raises).
- Use
T | Noneinstead ofOptional[T]. - Catch specific exceptions, never bare
except:or broadexcept Exception. - Use
logger.error()for errors, notprint(). - Line length: 88 characters (ruff default).
See CLAUDE.md for the full set of conventions enforced on this project.
- Create
camplinks/scrapers/{race}.pyextendingBaseScraper. - Implement
build_index_url(),collect_state_urls(),parse_state_page(). - Call
register_scraper("name", MyScraperClass)at module level. - Import the new module in
camplinks/__main__.py.
See USAGE.md for a full walkthrough with a Governor scraper example.
- Keep PRs focused on a single change.
- Include tests for new functionality.
- Ensure all checks pass before requesting review.