Contribution Guide¶
Setting Up the Environment¶
- Run
make install-uvto install uv if not already installed. - Run
make installto create the virtual environment and install all development dependencies.
Code Contributions¶
Workflow¶
- Fork the sqlspec repository.
- Clone your fork locally with
git. - Set up the environment.
- Create a dedicated feature or bugfix branch.
- Make your code changes and write tests.
- Run
make lintto run code formatters, Prek hooks, type checkers,slotscheck, and workflow audits. Always run this before committing; project setup intentionally does not install Git hook shims. - Commit your changes following the Conventional Commit format (for example,
fix(#100): resolve connection pooling leakorfeat: add database adapter feature). - Push the changes to your fork.
- Open a pull request with a descriptive title indicating what it changes and the corresponding issue number if applicable.
Tip
Pull requests and commits all follow the Conventional Commit format.
Guidelines for Writing Code¶
- Python Version & Typing:
- Python
3.11+baseline (>=3.11, <4.0). - All code must be fully typed (enforced via mypy and pyright). Avoid
Anywhenever possible. - Use PEP 585 built-in collection types (
dict,list,tuple,set) rather than theirtypingmodule equivalents. - Use PEP 604 union types (
T | None), neverOptional[T]orUnion[T, None]. -
Package modules must not import
from __future__ import annotations(enforced via Ruff ruleTID251). -
Comments & Documentation:
- Never use inline
#comments in Python code. If code requires explanation, document the rationale in the class or function docstring. - Use Google-style docstrings for public classes and functions with structured
Args:,Returns:, andRaises:blocks, and document every field on publicTypedDictandmsgspec.Structschemas with inline PEP 257 attribute docstrings. -
Explain why something is done in a specific way, not merely what the code does.
-
Naming Conventions:
- Functions, methods, and variables:
snake_case. - Classes, exceptions, and protocols:
PascalCase. -
Constants and module-level singletons:
SCREAMING_SNAKE_CASE. -
SQL Safety:
- SQL queries must always use parameterized placeholders (
:param,?,$1, or@param). -
Never use f-strings, string concatenation, or
%/.format()formatting to construct SQL statements with dynamic inputs. -
Linting & Code Quality:
- Formatting and linting are handled via Ruff and Prek.
make lintapplies Ruff fixes and formatting, runs every Prek hook, checks types and slots, and audits workflows withzizmor.- Dependency resolution uses a seven-day cooldown by default, with Litestar ecosystem packages exempt so coordinated releases remain testable.
Logging¶
- Logger names must follow the
sqlspec.<module>hierarchy. - Always obtain loggers via
sqlspec.utils.logging.get_loggerto ensure correlation and redaction filters are attached. - Use static event names in structured logs and include context fields instead of dynamic message strings.
Writing and Running Tests¶
- Test Style: Use
pytestfunction-based tests (test_*orasync def test_*). Do not use test classes. - Test Placement:
- Put behavior shared by adapters in the contract suite (
tests/integration/adapters/<database>/test_shared.py). - Keep vendor-only cases in that adapter's test folder (
tests/integration/adapters/<database>/<driver>/). - Use unit tests (
tests/unit/) for code that does not need a database (parsing, config normalization, parameter formatting). - Review the test placement guide for detailed fixture conventions.
- Integration Resources:
- Integration tests use
pytest-databasesfixtures to provision and manage database containers automatically. - The IBM Db2 tests start the Db2 Community Edition 11.5.9 image as a privileged container, so Docker must allow privileged containers.
- Coverage Requirements:
- The repository-wide coverage floor is 76%.
- Every new commit must keep changed-code coverage at or above 90%.
- Detect and eliminate N+1 queries for result mapping and list operations.
Run the smallest relevant test file first, then run the repository gates:
Mypyc and Performance Gates¶
SQLSpec keeps a 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:
For pull requests that change build hooks, wheel workflows, or compiled import boundaries, also run:
Benchmark claims need current artifacts rather than estimates:
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
Project Documentation¶
Documentation is authored in Markdown under docs/, configured via zensical.toml, and built with Zensical Free (zensical >= 0.0.71, MIT) and mkdocstrings-python (Griffe static AST analysis).
Authoring Guidelines and Runnable Examples¶
- Page Budgets: Keep conceptual guides and tutorials focused on one topic (
<= 12viewports) and Reference pages scoped to one primary class or cohesive symbol group (<= 120 KBHTML,<= 14"On this page"TOC items).Every example module is executed automatically by```{ .python title="docs/examples/quickstart/first_query.py" } --8<-- "docs/examples/quickstart/first_query.py:example" ```pytest tests/unit/docs/test_examples.py. - CLI Reference Generation: When modifying Click commands in
sqlspec/cli.py, regeneratedocs/reference/cli.mdwithuv run python -m tools.docs.generate_cli_docs --output docs/reference/cli.md.
Building and Serving Docs Locally¶
make docs runs zensical build --clean, generates site/llms.txt, site/llms-full.txt, and legacy .html redirect stubs (tools/docs/postbuild.py), and validates HTML budgets, anchors, and docstring hygiene (tools/docs/verify_docs_artifacts.py).
CLI Demo Recordings¶
SQLSpec uses VHS to record terminal demos as GIF files from docs/_tapes/*.tape into docs/_static/demos/:
Release Process¶
Releases follow Semantic Versioning and PEP 440. Release preparation is automated via Makefile targets:
See the SQLSpec Releases guide for versioning schemes, pre-release cadences, deprecation policies, and the automated CI publishing pipeline.
Next Steps for Contributors¶
- Creating Database Adapters — Build a new synchronous or asynchronous database adapter following SQLSpec's
config.py,core.py,driver.py,pool.py, anddata_dictionary.pyarchitecture. - Releases — Versioning policies, pre-release stages, mypyc/PGO wheel builds, and PyPI publishing workflows.
- Changelog — Historical release notes and upgrade guidance.