Contributing

Contributions are welcome. This page explains how the project is structured, what is and is not safe to change, and how to get a working development environment.

The generated HL7 models

Warning

Never edit anything inside hl7types/hl7/. Every file in that directory tree, messages, segments, groups, datatypes, and their __init__ modules, is generated automatically from the HL7 XML specification by hl7-parser. Any manual change will be silently overwritten the next time the generator runs.

If you find an inaccuracy in a generated model, a wrong field type, a missing component, an incorrect cardinality, the fix belongs in hl7-parser, not here. Once the generator is corrected and a new generation pass is run, the fix propagates to all versions and all affected types automagically.

Everything outside hl7types/hl7/ is hand-written and is fair game for contributions. Go mad!

Setting up a development environment

The project uses uv for dependency management.

git clone https://github.com/KeironO/hl7types.git
cd hl7types
uv sync --group dev --group docs
uv run pre-commit install

Running the tests

uv run pytest

Code style

The project uses ruff for linting and formatting. Pre-commit runs both automatically on every commit. To run them manually:

uv run ruff check --fix
uv run ruff format

Type checking is enforced with pyright:

uv run pyright

Pre-commit hooks run ruff, pyright, and the full test suite on every commit. A commit that fails any of these will be rejected locally before it reaches CI.

Building the documentation

uv run sphinx-build docs docs/_build/html

The built documentation will be available at docs/_build/html/index.html.

The HL7 reference pages (everything under the HL7 Reference section) are generated at build time by a custom Sphinx extension at docs/_ext/hl7_autodoc.py. Rather than using Sphinx’s standard autodoc, which would need to import every one of the 10,000 or so generated classes, hl7_autodoc parses the source files directly with Python’s ast module. It walks hl7types/hl7/ at the start of each build, extracts class names, field aliases, types, max_length constraints, and docstrings without executing any code, and writes one RST page per version per category (messages, segments, groups, datatypes) into docs/hl7/.

Those generated RST files are never committed to the repository. They are always produced fresh during the build. If you modify hl7_autodoc.py, the changes take effect on the next sphinx-build run. If you regenerate the HL7 models via hl7-parser, the reference pages update automatically on the next build with no further action required. I will fix this, eventually.