Contribution guide

Setting up the environment

1. Run make install-uv to install uv if not already installed 1. Run make install to install all dependencies and pre-commit hooks

Code contributions

Workflow

  1. Fork the sqlspec repository

  2. Clone your fork locally with git

  3. Set up the environment

  4. Make your changes

  5. Run make lint to run linters and formatters. This step is optional and will be executed automatically by git before you make a commit, but you may want to run it manually in order to apply fixes

  6. Commit your changes to git

  7. Push the changes to your fork

  8. Open a pull request. Give the pull request a descriptive title indicating what it changes. If it has a corresponding open issue, the issue number should be included in the title as well. For example a pull request that fixes issue bug: Increased stack size making it impossible to find needle #100 could be titled fix(#100): Make needles easier to find by applying fire to haystack

Tip

Pull requests and commits all need to follow the Conventional Commit format

Guidelines for writing code

  • All code should be fully typed. This is enforced via mypy.

  • All code should be tested. This is enforced via pytest.

  • All code should be properly formatted. This is enforced via black and Ruff.

Logging

  • Logger names must follow the sqlspec.<module> hierarchy.

  • Always obtain loggers via sqlspec.utils.logging.get_logger to ensure filters are attached.

  • Use static event names in structured logs and include context fields instead of dynamic message strings.

Writing and running tests

Todo

Write this section

Mypyc and performance gates

SQLSpec keeps a narrow compiled surface for hot paths. If a change touches pyproject.toml mypyc includes or excludes, tools/scripts/bench*.py, tools/scripts/mypyc_*.py, compiled sqlspec/core or sqlspec/driver modules, storage registry/pipeline code, data dictionary registry code, or adapter core.py / type_converter.py files, run the focused gates below before opening a pull request:

make test-mypyc
uv run python tools/scripts/mypyc_inventory.py

For pull requests that change build hooks, wheel workflows, or compiled import boundaries, also run:

make build-performance
uv run python tools/scripts/mypyc_smoke.py

Benchmark claims need current artifacts rather than estimates. Use JSON output when capturing baselines for review:

uv run python tools/scripts/bench.py --json-output /tmp/sqlspec-bench.json
uv run python tools/scripts/bench_gate.py --json-output /tmp/sqlspec-bench-gate.json
uv run python tools/scripts/bench_subsystems.py --json-output /tmp/sqlspec-bench-subsystems.json

CI gate ownership:

  • Pull requests always run lint, mypy, pyright, slotscheck, docs, and the Python test matrix through .github/workflows/ci.yml.

  • Pull requests that touch build configuration run .github/workflows/test-build.yml. The default pull-request path builds a subset mypyc wheel matrix; maintainers can dispatch the full architecture matrix when release confidence is needed.

  • Releases run .github/workflows/publish.yml with standard wheels, mypyc wheels, PGO on Linux and macOS, and mypyc smoke imports before publishing.

  • .github/workflows/pgo-validate.yml is manual Linux PGO validation. It is useful for build-hook changes but is not required for every pull request.

  • Optional services and container-backed adapter benchmarks remain manual unless their owning PR explicitly opts into those dependencies.

Project documentation

The documentation is located in the /docs directory and is ReST and Sphinx. If you're unfamiliar with any of those, ReStructuredText primer and Sphinx quickstart are recommended reads.

Running the docs locally

You can serve the documentation with make docs-serve, or build them with make docs.

CLI demo recordings

SQLSpec uses VHS to record terminal demos as GIF files that are embedded in the documentation.

Requirements: VHS, ffmpeg, ttyd

Installation:

go install github.com/charmbracelet/vhs@latest

Recording demos:

make docs-demos

This will process every .tape file in docs/_tapes/ and write GIF output to docs/_static/demos/.

Creating a new tape:

  1. Create a new .tape file in docs/_tapes/.

  2. Use the standard header (see existing tapes for examples). All tapes should use the Catppuccin Mocha theme, font size 14, and 1000x600 dimensions.

  3. Use Hide/Show commands to hide setup steps like virtual environment activation.

  4. Include generous Sleep durations after commands that produce output.

  5. Run make docs-demos to generate the GIF.

  6. Reference the GIF in your documentation with an .. image:: directive pointing to /_static/demos/<name>.gif.

Building docs with demos:

make docs-all

Creating a new release

  1. Increment the version in pyproject.toml.

    Note

    The version should follow semantic versioning and PEP 440.

  2. Draft a new release on GitHub

    • Use vMAJOR.MINOR.PATCH (e.g. v1.2.3) as both the tag and release title

    • Fill in the release description. You can use the "Generate release notes" function to get a draft for this

  3. Commit your changes and push to main

  4. Publish the release

  5. Go to Actions and approve the release workflow

  6. Check that the workflow runs successfully