Contributor Guide¶
First off, thank you for considering contributing to hiperhealth! We welcome
all contributions, from bug reports to new features and documentation
improvements. This guide provides everything you need to get your development
environment set up and start contributing.
Following these guidelines helps to communicate that you respect the time of the developers managing and developing this open source project. In return, they should reciprocate that respect in addressing your issue or assessing patches and features.
Table of Contents¶
- Code of Conduct
- Project Layout
- Getting Started: Local Setup
- Development Workflow
- Running the Applications
- Database Migrations
- Code Style & Linting
- Running Tests
- Types of Contributions
- Architectural Overview
- Pull Request Guidelines
- Submitting Changes
- Release Process
Code of Conduct¶
This project and everyone participating in it is governed by the Code of Conduct. By participating, you are expected to uphold this code.
Project Layout¶
This project uses the src layout, which means that the package code is located
at ./src/hiperhealth.
For more information, check the official documentation: https://packaging.python.org/en/latest/discussions/src-layout-vs-flat-layout/
1. Getting Started: Local Setup¶
This project uses Conda to manage environments, Uv/Setuptools to manage dependencies, and Makim to streamline development tasks.
Uv/Setuptools is a Python package management tool that simplifies the process of building and publishing Python packages. It allows us to easily manage dependencies, virtual environments, and package versions. Uv/Setuptools also includes features such as dependency resolution, lock files, and publishing to PyPI.
Tech Stack Overview¶
As the core clinical AI engine, this repository relies on:
- Python 3.10+ for core logic.
- LiteLLM for flexible, provider-agnostic AI model integration.
- Pydantic / FHIR for strict medical data validation.
- Douki for docstring and documentation generation.
- Makim as the task runner.
Prerequisites¶
- Python 3.10+
- Conda installed on your system.
Installation¶
-
Fork & Clone the Repository: Start by forking the repository on GitHub, then clone your fork locally:
-
Create the Development Environment: Set up a Conda virtual environment using the provided
conda/dev.yamlfile:Alternatively, if you have
mambainstalled, you can use it for faster environment creation: -
Install Project Dependencies: This command installs all required packages.
-
(Optional) Set Up API Keys: Note: The core
hiperhealthlibrary is designed to be functional without external dependencies. However, specific modules (such as certain AI Agents or evaluation scripts) may optionally require API keys (e.g.,OPENAI_API_KEY).If you are working on a module that requires external services:
-
Create a .env file at the root or within .envs/.env.
-
Add the required keys as environment variables.
-
2. Development Workflow¶
All common development tasks are managed via makim commands defined in
.makim.yaml.
The core of the hiperhealth library is its set of Pydantic models in
src/hiperhealth/schema/. These serve as the source of truth for all medical
data structures.
If you modify a Pydantic schema that requires a database change:
- Regenerate the SQLAlchemy Models:
Code Style & Linting¶
We enforce code quality and a consistent style using pre-commit hooks,
configured in .pre-commit-config.yaml.
- Install Git Hooks:
The hooks will now run automatically on every commit. Usually, the verification will only run on the files modified by that commit, but the verification can also be triggered for all the files using:
If you would like to skip the failing checks and push the code for further
discussion, use the --no-verify option with git commit.
- Run Hooks Manually: To run the checks on all files at any time:
Running Tests¶
Our test suite uses pytest.
- Run All Tests:
- Run Tests with Coverage Report:
Types of Contributions¶
You can contribute to hiperhealth in many ways:
Report Bugs¶
Report bugs at GitHub Issues.
If you are reporting a bug, please include:
- Your operating system name and version.
- Any details about your local setup that might be helpful in troubleshooting.
- Detailed steps to reproduce the bug.
Fix Bugs¶
Look through the GitHub issues for bugs. Anything tagged with "bug" and "help wanted" is open to whoever wants to implement it.
Implement Features¶
Look through the GitHub issues for features. Anything tagged with "enhancement" and "help wanted" is open to whoever wants to implement it.
Write Documentation¶
hiperhealth could always use more documentation, whether as part of the official hiperhealth docs, in docstrings, or even on the web in blog posts, articles, and such.
Submit Feedback¶
The best way to send feedback is to file an issue at GitHub Issues.
If you are proposing a feature:
- Explain in detail how it would work.
- Keep the scope as narrow as possible, to make it easier to implement.
- Remember that this is a volunteer-driven project, and that contributions are welcome :)
3. Architectural Overview¶
Pipeline and Skills¶
The library is built around a skill-based pipeline architecture:
StageRunner (executes any stage independently)
|
+-- Registered Skills (run in registration order per stage)
| +-- PrivacySkill -> screening, intake
| +-- ExtractionSkill -> intake
| +-- DiagnosticsSkill -> diagnosis, exam
| +-- (custom skills) -> any combination of stages
|
+-- Usage patterns:
+-- runner.run("screening", ctx) # Monday, nurse
+-- runner.run("diagnosis", ctx) # Wednesday, physician A
+-- runner.run("treatment", ctx) # Friday, physician B
+-- runner.run_many([...], ctx) # batch
Key concepts:
- Stages are independently executable clinical phases (screening, intake, diagnosis, exam, treatment, prescription)
- Skills are composable plugins (
BaseSkillsubclasses) that declare which stages they affect viaSkillMetadata - PipelineContext is a Pydantic model that carries all data between stages and serializes to JSON for persistence between invocations
- StageRunner orchestrates skill execution: for each stage, it runs all
matching skills'
pre()->execute()->post()hooks in registration order - SkillRegistry manages skill installation (from local paths or Git URLs)
and loading. Skills are stored in
~/.hiperhealth/skills/and activated viarunner.register("skill-name") - hiperhealth.yaml is a metadata file every skill project must include, declaring name, version, entry point, and stages
Source layout:
src/hiperhealth/pipeline/— core engine (stages, context, skill base classes, runner, registry, discovery)src/hiperhealth/skills/— built-in skills (diagnostics, extraction, privacy)src/hiperhealth/agents/— shared utilities (e.g.client.py) and backward-compatible re-exports fromskills/
See Creating Skills for a guide on writing custom skills.
Schema-First Data Layer¶
The library follows a "schema-first" approach for its database models.
- Pydantic Schemas (
src/hiperhealth/schema/): These are the primary source of truth. They define the data structures and validation rules for our application. - SQLAlchemy Models (
src/hiperhealth/models/sqla/): These ORM models are auto-generated from the Pydantic schemas using thescripts/gen_models/gen_sqla.pyscript (makim gen.fhir-models). Do not edit these files manually.
Pull Request Guidelines¶
Before you submit a pull request, check that it meets these guidelines:
- The pull request should include tests.
- If the pull request adds functionality, the docs should be updated. Put your new functionality into a function with a docstring, and add the feature to the list in README.md.
- The pull request should work for Python >= 3.10.
- Ensure that the commit message follows the Angular Commit Message Conventions.
4. Submitting Changes¶
- Create a new branch for your feature or bugfix.
- Make your changes, ensuring you add tests for any new functionality.
- Ensure all tests pass and the linter is happy.
- Push your branch to your fork and open a Pull Request against the
mainbranch of the upstream repository. - In your PR description, clearly explain the problem and your solution. Include the relevant issue number if applicable.
Release Process¶
This project uses semantic-release in order to cut a new release based on the commit message.
Commit Message Format¶
semantic-release uses the commit messages to determine the consumer impact of changes in the codebase. Following formalized conventions for commit messages, semantic-release automatically determines the next semantic version number, generates a changelog, and publishes the release.
By default, semantic-release uses
Angular Commit Message Conventions.
The commit message format can be changed with the preset or config options
of the
@semantic-release/commit-analyzer
and
@semantic-release/release-notes-generator
plugins.
Tools such as commitizen or commitlint can be used to help contributors and enforce valid commit messages.
The table below shows which commit message gets you which release type when
semantic-release runs (using the default configuration):
| Commit message | Release type |
|---|---|
fix(pencil): stop graphite breaking when pressure is applied |
Fix Release |
feat(pencil): add 'graphiteWidth' option |
Feature Release |
perf(pencil): remove graphiteWidth option |
Chore |
feat(pencil)!: The graphiteWidth option has been removed |
Breaking Release |
Note: For a breaking change release, use ! at the end of the message prefix.
Source: https://github.com/semantic-release/semantic-release/blob/master/README.md#commit-message-format
As this project uses the squash and merge strategy, ensure to apply the commit
message format to the PR's title.